视图模型初始化后,依赖项属性不起作用
我想编写一个自定义异步图像容器自定义控件。视图模型初始化后,依赖项属性不起作用
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<custom:CustomImage Width="64" Height="64" BaseUri="{Binding Uri}" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Items属性是对象的名单我在MainWindowViewModel初始化:
public List<A> Items { get; set; } = new List<A>();
和
foreach (XmlNode item in doc.LastChild.FirstChild.SelectNodes(".//item"))
{
Items.Add(
new A
{
Title = item.FirstChild.InnerText,
Uri = new Uri(item.SelectNodes(".//enclosure")[0].Attributes["url"].Value)
}
);
}
我想我已经从该控件创建的列表在自定义控件上设置一个Dependency Property(你可以在上面看到:BaseUri =“{Binding Uri}”。Uri是类A的一个属性。
这是DP实现:
public Uri BaseUri
{
get { return (Uri)GetValue(BaseUriProperty); }
set { SetValue(BaseUriProperty, value); }
}
public static readonly DependencyProperty BaseUriProperty =
DependencyProperty.Register("BaseUri", typeof(Uri),
typeof(CustomImage), new FrameworkPropertyMetadata(default(Uri), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
仅在CustomImage自定义控件没有任何视图模型它的工作原理。如果我在CustomImage的构造函数中这样做:
DataContext = new CustomImageViewModel();
它不起作用了。
任何想法?
你不应该明确地设置UserControl的DataContext。这样做有效地防止在DataContext从控制的父继承,因为它是由一个结合样
BaseUri="{Binding Uri}"
所以需要,从控制的构造函数删除行
DataContext = new CustomImageViewModel();
。
当您没有明确设置时,“控件没有任何视图模型”是不正确的。实际上,视图模型(或继承的DataContext)通过ItemsControl的项目容器设置为ItemsSource
集合中的相应项目。因此,您控件的DataContext
会自动设置为您的类A
的一个实例。
但我想要一个包含我需要的所有异步操作(和其他可绑定属性)的自定义控件的单独视图模型。可能吗? – Panthesilea
“有可能吗?”是的,但它没有意义。你想绑定你的控件的属性,比如'BaseUri =“{Binding Uri}”',所以必须继承DataContext。 – Clemens
哦,我明白了。谢谢! – Panthesilea
除了答案中的内容,您应该使用'ObservableCollection '而不是'List '作为Items属性的类型,以便在向集合中添加项目或从集合中删除项目时启用内置更改通知。 – Clemens
默认情况下(或根本),“BaseUri”属性双向绑定似乎并不合理。 – Clemens
最后,“异步图像容器”看起来很奇怪,当你可以使用Image控件并将其Source属性设置为已经实现异步加载的BitmapImage时。 – Clemens