【问题标题】:Dependency Property does not work after view model was initialized初始化视图模型后,依赖属性不起作用
【发布时间】:2017-02-09 12:22:07
【问题描述】:

我想写一个自定义的异步图像容器自定义控件。我从这个控件创建了一个列表:

<ItemsControl ItemsSource="{Binding Items}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Grid>
                <custom:CustomImage Width="64" Height="64" BaseUri="{Binding Uri}" />
            </Grid>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Items 属性是我在 MainWindowViewModel 中初始化的对象 A 的列表:

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)
        }
    );
}

我想在自定义控件上设置一个依赖属性(你可以在上面看到: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();

它不再起作用了。

有什么想法吗?

【问题讨论】:

  • 除了答案中所说的之外,您应该使用ObservableCollection&lt;A&gt; 而不是List&lt;A&gt; 作为Items 属性的类型,以便在添加或删除项目时启用内置更改通知集合。
  • BaseUri 属性默认(或根本)绑定双向似乎也没有意义。
  • 最后,“异步图像容器”看起来很奇怪,因为您可以使用 Image 控件并将其 Source 属性设置为已经实现异步加载的 BitmapImage。

标签: c# wpf data-binding custom-controls dependency-properties


【解决方案1】:

您永远不应该显式设置 UserControl 的 DataContext。这样做可以有效地防止 DataContext 从控件的父级继承,因为它是诸如

之类的绑定所必需的
BaseUri="{Binding Uri}"

所以,删除该行

DataContext = new CustomImageViewModel();

来自控件的构造函数。


当您没有明确设置时,“控件没有任何视图模型”是不正确的。事实上,视图模型(或继承的 DataContext)通过 ItemsControl 的项容器设置为来自ItemsSource 集合的适当项。因此,您的控件的DataContext 会自动设置为您的类A 的实例。

【讨论】:

  • 但是我想要一个包含我需要的所有异步操作(和其他可绑定属性)的自定义控件的单独视图模型。有可能吗?
  • “有可能吗?”是的,但这没有意义。您想绑定控件的属性,例如BaseUri="{Binding Uri}",因此必须继承 DataContext。
  • 哦,我明白了。谢谢!
猜你喜欢
  • 1970-01-01
  • 2012-07-25
  • 2021-10-09
  • 1970-01-01
  • 1970-01-01
  • 2014-08-24
  • 2013-12-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多