我谷歌了很多,阅读了几乎所有SO自定义控件/CollectionViewSource/Collection binding/dependency properties binding等问题,并尝试了一些类似问题的解决方案,如this one和this以及some more,但仍然不起作用。我可能错过了什么,但我不知道是什么。
以下是自定义控件类的相关部分:
public class CustomComboBox : Control
{
static CustomComboBox()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomComboBox), new FrameworkPropertyMetadata(typeof(CustomComboBox)));
}
public CustomComboBox()
{
CustomItems = new ObservableCollection<ComboBoxItem>();
DataContext = this;
}
internal ObservableCollection<ComboBoxItem> CustomItems
{
get { return (ObservableCollection<ComboBoxItem>)GetValue(CustomItemsProperty); }
set { SetValue(CustomItemsProperty, value); }
}
// Using a DependencyProperty as the backing store for CustomItems. This enables animation, styling, binding, etc...
public static readonly DependencyProperty CustomItemsProperty =
DependencyProperty.Register("CustomItems", typeof(ObservableCollection<ComboBoxItem>), typeof(CustomComboBox), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
private string text;
public string Text
{
get { return text; }
set
{
text = value;
OnPropertyChanged("Text");
}
}
// More properties, events and functions...
}
以及 XAML 代码中相关的部分:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyNamespace"
xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
x:Class="CustomComboBox">
<CollectionViewSource x:Key="GroupedData"
Source="{Binding Path=CustomItems, RelativeSource={RelativeSource FindAncestor, AncestorType=local:CustomComboBox}, diag:PresentationTraceSources.TraceLevel=High}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="GroupName" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
<!-- ...Some more Styles and DataTemplates... -->
<Style TargetType="{x:Type local:CustomComboBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:CustomComboBox}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ComboBox IsEditable="True"
Text="{Binding Text}"
ItemsSource="{Binding Source={StaticResource GroupedData}}">
<!-- ...Some more properties... -->
</ComboBox>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
我从 System.Diagnostics
得到了这个输出:
System.Windows.Data Warning: 60 : BindingExpression (hash=28932383): 默认模式解析为单向绑定
System.Windows.Data Warning: 61 : BindingExpression (hash=28932383): 默认更新触发器解析为属性更改
System.Windows.Data Warning: 62 : BindingExpression (hash=28932383): 附加到 System.Windows.Data.CollectionViewSource.Source (hash=23914501)
System.Windows.Data Warning: 66 : BindingExpression (hash=28932383): 相对源 (FindAncestor) 需要树上下文
System.Windows.Data Warning: 65 : BindingExpression (hash=28932383): 延迟解析源
System.Windows.Data Warning: 67 : BindingExpression (hash=28932383): 解析源
System.Windows.Data Warning: 70 : BindingExpression (hash=28932383): 找到数据上下文元素: (OK)
System.Windows.Data Warning: 67 : BindingExpression (hash=28932383): 解析源
System.Windows.Data Warning: 70 : BindingExpression (hash=28932383): 找到数据上下文元素: (OK)
System.Windows.Data Warning: 67 : BindingExpression (hash=28932383): 解析源 (最后机会)
System.Windows.Data Warning: 70 : BindingExpression (hash=28932383): 找到数据上下文元素: (OK)
System.Windows.Data Error: 4 : 找不到绑定引用的源'RelativeSource FindAncestor, AncestorType='MyNamespace.CustomComboBox', AncestorLevel='1''. BindingExpression:Path=CustomItems; DataItem=null; 目标元素为 'CollectionViewSource' (HashCode=23914501); 目标属性为 'Source' (类型 'Object')
我首先尝试了这个绑定:<CollectionViewSource x:Key="GroupedData"
Source="{Binding CustomItems}">
但是我遇到了以下错误:
System.Windows.Data Error: 2 : 找不到目标元素的主要FrameworkElement或FrameworkContentElement。 BindingExpression:Path=CustomItems; DataItem=null; 目标元素为 'CollectionViewSource' (HashCode=37908782); 目标属性为 'Source' (类型为'Object')
顺便提一下,ComboBox内部绑定到其他属性也可以正常工作,比如Text
绑定。
Window
(或UserControl
)设置一些视图模型作为DataContext
,并期望它对您定义的所有控件都可用。但是,在这种情况下,如果您设置DataContext = this
,则CustomComboBox
(以及其所有可视后代)将不再继承视图模型作为数据上下文。这意味着您将无法将任何属性绑定到视图模型属性,除非显式指定绑定源,或将DataContext
设置为适当的值。 - Grx70CustomComboBox
属性而不是模板元素的属性。使用“传统”方式,OP将无法绑定CustomItems
属性或其他经常绑定的属性(如Visibility
或IsEnabled
)。 - Grx70