我对MVVM样式项目中外部库中有用的用户控件 Monitor 感兴趣。
一切看起来很好......但是这个控件有简单的(不依赖)只读属性(IList<ILogSource>
),我需要填充它。
在思考了一下后,我决定用其他控件 MonitorWrap 包装 Monitor 控件:
<UserControl
x:Class="Prj.CustomControls.MonitorWrap"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:catel="http://catel.codeplex.com"
xmlns:uc="clr-namespace:UsefulControll;assembly=UsefulControll">
<uc:Monitor x:Name="Monitor" />
</UserControl>
在代码后面我创建依赖属性:
public partial class MonitorWrap : UserControl
{
/// <summary>
/// Initializes a new instance of the <see cref="MonitorWrap"/> class.
/// </summary>
public MonitorWrap()
{
InitializeComponent();
DataContextChanged += (sender, args) =>
{
//correct ViewModel sets to DataContext
};
}
public IList<ILogSource> LogSources
{
get { return (IList<ILogSource>)GetValue(LogSourcesProperty); }
set { SetValue(LogSourcesProperty, value); }
}
// Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc...
public static readonly DependencyProperty LogSourcesProperty =
DependencyProperty.Register("LogSources", typeof(IList<ILogSource>), typeof(MonitorWrap), new PropertyMetadata(null,ChangeCallback));
private static void ChangeCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var logControlPanelView = d as MonitorWrap;
//add elements from LogSources to readonly collection property.
}
}
父xml的下一步:
<customControls:MonitorWrap LogSources="{Binding Sources}"/>
我希望我会在Change Callback方法中填充集合,但它不起作用。
所以问题:
ChangeCallback
方法不起作用。 P.S。
我正在使用MVVM框架并且DataContext
设置正确(MonitorWrap
构造函数中的lambda表达式工作正常)。
ViewModel实现INotifyPropertyChanged
和代码
protected override void OnPropertyChanged(AdvancedPropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
if (e.PropertyName == "Sources")
{
//works fine on property changed
}
}
也可以。
答案 0 :(得分:1)
IList<ILogSource>
看起来很可疑,就像你可能会要求更多C#对协方差的支持而不是你会得到的。
viewmodel属性的类型必须可分配给IList<ILogSource>
,并且其规则相当严格。
从根本上说,ObservableCollection<ILogSource>
是IList<ILogSource>
,但它不是IList<ILogSource_inherited_Class>
。不只是绑定不能做到这一点。您可以将项目从一个复制到另一个,但不能投射。你想要做的只是复制,但类型系统不知道 - 它只是看到你试图做任务。
使用类型IEnumerable<ILogSource>
(see fiddle)的依赖项属性应该起作用。您需要做的就是将项目复制出来,这样就足够了。如果您需要的只是IList<ILogSource>
,请不要告诉编译器您需要IEnumerable<ILogSource>
可以执行的所有操作。