gpt4 book ai didi

wpf - "group"项目 "virtually"的最佳方法?

转载 作者:行者123 更新时间:2023-12-05 01:21:21 25 4
gpt4 key购买 nike

我正在开发基于 WPF 控件的自定义项。对于“正常”布局,请考虑垂直 StackPanel,所以我的 xaml 看起来像:

<mycontrol>
<item1 />
<item2 />
<item3 />
</mycontrol>

在这种情况下,创建了简单的 3 项容器,一切都很好。控件将如下所示:
[item1]
[item2]
[item3]

用例 #2 是,我需要支持水平“分组”......理想情况下,我的 xaml 看起来像:
<mycontrol>
<item1 />
<stackpanel orientation=horizontal>
<item2a />
<item2b />
<item2c />
</stackpanel>
<item3 />
</mycontrol>

在这种情况下,我将呈现为:
[item1]
[item2a] [item2b] [item2c]
[item3]

所以,我要做的是生成 5 个元素容器。我已经制定了一个自定义布局面板并且该部分有效。

问题是,如果我使用堆栈面板,我只会得到 3 个项目容器,这是有道理的,呃,但它会破坏控件的键盘界面。在这种情况下,我可以做一些骇人听闻的事情,拦截所有键盘和鼠标的东西并“重新路由”它,但这似乎很骇人听闻,而且很难以通用的方式开始工作。

WPF 中是否有一些晦涩的东西来处理这个问题?作为自己的容器生成的“子项目”?

我目前的方式是做类似的事情:
<item1 />
<item2a isGrouped=true />
<item2b isGrouped=true />
<item2c isGrouped=true />
<item3 />

所以,当我点击第一个 isGrouped=true 时,它​​会开始分组,直到它达到 false,但我也不对此感到疯狂,因为我必须将 isGrouped 设为 3 状态枚举,这样我才能拥有一个正确的组低于另一组。此外,xaml 中的层次结构也不清楚。

有什么建议么?

最佳答案

使用 HierarchicalDataTemplate,我能够或多或少地获得您想要的外观。在 TreeView 内使用自定义 TreeViewItem控制模板。对于控件模板,我只是复制了example template并做了一些修改。所有的容器都在正确的位置,但是键盘导航在嵌套项上不起作用(因为 TreeView 并不期待我猜的那种布局)。这是我想出的:

<TreeView
ItemsSource="{Binding Items}">
<TreeView.Resources>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Style
TargetType="{x:Type TreeViewItem}">
<Setter
Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter
Property="IsExpanded"
Value="True" />
<Setter
Property="Template">
<Setter.Value>
<!-- This template came from the example template and has just a few modifications.
Example is at: https://msdn.microsoft.com/en-us/library/ms752048.aspx -->
<ControlTemplate
TargetType="{x:Type TreeViewItem}">
<Grid>
<!-- Changed the grid configuration -->
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- The entire VisualStateGroups section is a direct copy+paste from the example template -->
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="SelectionStates">
<VisualState x:Name="Selected">
<Storyboard>
<ColorAnimationUsingKeyFrames
Storyboard.TargetName="Bd"
Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
<EasingColorKeyFrame
KeyTime="0"
Value="{StaticResource SelectedBackgroundColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unselected" />
<VisualState x:Name="SelectedInactive">
<Storyboard>
<ColorAnimationUsingKeyFrames
Storyboard.TargetName="Bd"
Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
<EasingColorKeyFrame
KeyTime="0"
Value="{StaticResource SelectedUnfocusedColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="ExpansionStates">
<VisualState x:Name="Expanded">
<Storyboard>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="ItemsHost">
<DiscreteObjectKeyFrame
KeyTime="0"
Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Collapsed" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<!-- Removed the ToggleButton -->
<!-- Tweaked the placement of items in the grid -->
<Border
x:Name="Bd"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}">
<ContentPresenter
x:Name="PART_Header"
ContentSource="Header"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>
</Border>
<ItemsPresenter
x:Name="ItemsHost"
Grid.Column="1" />
</Grid>
<ControlTemplate.Triggers>
<!-- Removed the IsExpanded trigger -->
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="HasHeader" Value="false" />
<Condition Property="Width" Value="Auto" />
</MultiTrigger.Conditions>
<Setter
TargetName="PART_Header"
Property="MinWidth"
Value="75" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="HasHeader" Value="false" />
<Condition Property="Height" Value="Auto" />
</MultiTrigger.Conditions>
<Setter
TargetName="PART_Header"
Property="MinHeight"
Value="19" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TreeView.Resources>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate
DataType="{x:Type local:MyItem}"
ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>

作为引用,我的 ItemsSource属性绑定(bind)到包含如下项目的集合:
internal class MyItem
{
public string Name { get; private set; }

public List<MyItem> Children { get; private set; }

public MyItem(string name = null)
{
Name = name;
Children = new List<MyItem>();
}
}

这是在没有创建自定义控件的情况下完成的,但希望它能让您了解您可以做什么。 HeirarchicalDataTemplate 的组合一个专门的容器类型(在我的例子中是 TreeViewItem 带有自定义控件模板)是我这样做的关键。

这是我测试的一些数据和结果:
public IEnumerable<MyItem> Items { get; private set; }

...

var items = new MyItem[]
{
new MyItem("[First]"),
new MyItem(),
new MyItem("[Third]")
};
items[1].Children.Add(new MyItem("[Second_0]"));
items[1].Children.Add(new MyItem("[Second_1]"));
items[1].Children.Add(new MyItem("[Second_2]"));
Items = items;

Screenshot

我相信可视化可以得到改善。我只是在 10 分钟内把它拼凑在一起。

关于wpf - "group"项目 "virtually"的最佳方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30812581/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com