至于问题,我已经创建了一个自定义的UserControl
。它有一个ItemsControl
,其中ItemsSource
被绑定到一个可绑定的属性DependecyProperty
。
我的控件XAML:
<Grid>
<ItemsControl ItemsSource="{Binding Path=InternalControl}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
我的控制代码:
public static readonly DependencyProperty SetInternalControlProperty =
DependencyProperty.Register(
nameof(ObservableCollection<dynamic>),
typeof(ObservableCollection<dynamic>),
typeof(UtilityExpander));
public ObservableCollection<dynamic> InternalControl
{
get { return (ObservableCollection<dynamic>)GetValue(SetInternalControlProperty); }
set { SetValue(SetInternalControlProperty, value); }
}
主要XAML:
<Controls:UtilityExpander InternalControl="{Binding GasControl}"/>
主要代码:
private ObservableCollection<UtilityGas> _gasControl;
public ObservableCollection<UtilityGas> GasControl { get => _gasControl; set { _gasControl = value; NotifyPropertyChanged(); } }
在InitializeComponent()
上运行时,我得到
System.Windows.Markup.XamlParseException: '无法在型别' UtilityExpander '的' InternalControl '属性上设定' Binding'。只能在DependencyObject的DependencyProperty上设定'Binding'。'
我使用dynamic
的原因是我想使用不同类型IEnumerable<objects>
的控件
1条答案
按热度按时间ui7jx7zq1#
There are two errors in the declaration of the dependency property.
The second argument of the Register method must be the name of the property, not that of the property's type. The backing field must be named like the property, with the suffix
Property
.Besides that, the property would be more usable if it would be declared as
IEnumerable<dynamic>
. Whether its value implementsINotifyCollectionChanged
or not could be checked at runtime.The
dynamic
collection type argument seems also redundant. When you declare the property like shown below, you can assign any type of collection, even with different element types in a single collection instance. This is by the way how theItemsSource
property is defined.Finally, you should also avoid to set the DataContext of your control to itself, because that breaks the standard data binding behaviour of the control's properties, e.g.
InternalControl="{Binding GasControl}"
.Bind to the own property in the control's XAML with an ElementName or RelativeSource Binding: