我创建了一个自定义ComboBox
,如下所示:(注意,代码不正确但你应该得到一般的想法。)ComboBox
包含2个依赖属性,它们很重要:TitleText
和DescriptionText
。
<Grid>
<TextBlock x:Name="Title"/>
<Grid x:Name="CBG">
<ToggleButton/>
<ContentPresenter/>
<Popup/>
</Grid>
</Grid>
我想使用此ComboBox
来显示各种选项。我创建了一个名为Setting的类,它继承自DependencyObject
以创建可用的项目,我创建了一个DataTemplate
来将此Settings
对象的内容绑定到我的ComboBox
并创建了一个{ {1}}包含UserControl
,其中包含我之前提到的ItemsControl
模板。我可以用DataTemplate
个对象填充它。
Setting
我希望获得所选<DataTemplate x:Key="myDataTemplate">
<ComboBox TitleText="{Binding Title}" DescriptionText="{Binding DescriptionText}"/>
</DataTemplate>
<UserControl>
<Grid>
<StackPanel Grid.Column="0">
<ItemsControl Template="{StaticResource myDataTemplate}">
<Item>
<Setting Title="Foo" Description="Bar">
<Option>Yes</Option><Option>No</Option>
</Setting>
</Item>
</ItemsControl>
</StackPanel>
<StackPanel Grid.Column="1">
<TextBlock x:Name="Description"/>
</StackPanel>
</Grid>
</UserControl>
的{{1}}(由DescriptionText
控件的ComboBox
或IsFocus
属性选择popup)放在ComboBox
的{{1}} IsOpen
中。
我设法实现这一目标的一种方法是将Description
替换为TextBlock
,但这会导致几个问题:即使我禁用了滚动条,它总是显示滚动条,当我的弹出窗口已打开,但只有当我在UserControl
中明确选择了该项目时,当我启用ItemsControl
属性时,ListBox
的内容根本不会显示,我不得不重新开始-theme ListBox
控件以匹配我的OverridesDefaultStyle
布局......
在不使用ListBox
或创建自定义ListBox
控件的情况下,让UserControl
显示的最佳和最简单方法是什么(因为它与{{1具有相同的效果}})?
最后的目标是遍历所有项目(可能将它们变为DescriptionText
或某种类型,并将它们保存到我的设置文件中。
答案 0 :(得分:1)
我想我知道你要做什么。这是一个可能的解决方案。
您应该使用ListBox(或从Selector控件派生的任何内容)才能使用SelectedItem属性。
<UserControl>
<Grid>
<StackPanel Grid.Column="0">
<ListBox x:Name="SettingListBox" Template="{StaticResource myDataTemplate}">
<Item>
<Setting Title="Foo" Description="Bar">
<Option>Yes</Option><Option>No</Option>
</Setting>
</Item>
</ListBox >
</StackPanel>
<StackPanel Grid.Column="1">
<TextBlock x:Name="Description"
Text="{Binding SelectedItem.Description, ElementName=SettingListBox}"/>
</StackPanel>
</Grid>
</UserControl>
要解决打开ComboBox下拉菜单时ListBox没有关注项目的问题,我有一个附加属性可以为您解决这个问题。
public class ListBoxHelper
{
#region Dependency Property
public static bool GetCanFocusParent(DependencyObject obj)
{
return (bool)obj.GetValue(CanFocusParentProperty);
}
public static void SetCanFocusParent(DependencyObject obj, bool value)
{
obj.SetValue(CanFocusParentProperty, value);
}
// Using a DependencyProperty as the backing store for CanFocusParent. This enables animation, styling, binding, etc...
public static readonly DependencyProperty CanFocusParentProperty =
DependencyProperty.RegisterAttached("CanFocusParent", typeof(bool), typeof(ListBoxHelper), new UIPropertyMetadata(false, OnCanFocusParentChanged));
#endregion
private static void OnCanFocusParentChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
var element = obj as UIElement;
if(element == null) return;
if((bool)args.NewValue)
element.PreviewMouseDown += FocusOnParent;
else
element.PreviewMouseDown -= FocusOnParent;
}
private static void FocusOnParent(object sender, RoutedEventArgs e)
{
var listBoxItem = VisualUpwardSearch<ListBoxItem>(sender as DependencyObject) as ListBoxItem;
if (listBoxItem != null) listBoxItem.IsSelected = true;
}
public static DependencyObject VisualUpwardSearch<T>(DependencyObject source)
{
while (source != null && source.GetType() != typeof(T))
source = VisualTreeHelper.GetParent(source);
return source;
}
}
这个小课程的作用是帮助你的控件在你激活其中的控件(即你的ComboBox)时专注于ListBox选择的项目。在ListBox项目中单击鼠标时,它可以正常工作。
现在你所要做的就是将它附加到你的ComboBox上,如下所示:
<DataTemplate x:Key="myDataTemplate">
<ComboBox
TitleText="{Binding Title}"
DescriptionText="{Binding DescriptionText}"
CotrolHelper:ListBoxHelper.CanFocusParent="true"/>
</DataTemplate>
ControlHelper的位置:
xmlns:ControlHelper="clr-namespace:WhereYouPutYour.ListBoxHelperClass"
最后,要禁用(但我建议设置为Auto)滚动条,您可以使用ListBox中的ScrollViewer附加属性,如下所示:
<ListBox
x:Name="SettingListBox"
Template="{StaticResource myDataTemplate}"
ScrollViewer.VerticalScrollBarVisibility="Disabled" >
<Item>
<Setting Title="Foo" Description="Bar">
<Option>Yes</Option><Option>No</Option>
</Setting>
</Item>
</ListBox >
答案 1 :(得分:0)
您可以使用ListBox,只需更改数据的显示方式。例如,此代码默认不具有滚动条。 (我想要滚动条,所以我必须在ScrollViewer中明确地包装整个内容。)
<ListBox.Template>
<ControlTemplate>
<StackPanel IsItemsHost="True" >
</StackPanel>
</ControlTemplate>
</ListBox.Template>