【问题标题】:Understanding dependancy objects了解依赖对象
【发布时间】:2014-11-21 13:14:08
【问题描述】:

我完全迷失了依赖对象和绑定。我经常在不了解原因和方式的情况下让事情正常进行,这个问题是关于知道应该发生什么。

我有一个带有以下 XAML 的小型用户控件

<Grid>
    <Image Source="{Binding Icon}"></Image>
    <TextBlock Text="{Binding Title}"></TextBlock>
</Grid>

我的代码后面有以下内容

    public static readonly DependencyProperty IconProperty =
     DependencyProperty.Register("Icon", typeof(Image), typeof(MenuItem));

    public Image Icon
    {
        get { return (Image)GetValue(IconProperty); }
        set { SetValue(IconProperty, value); }
    }

    public static readonly DependencyProperty TitleProperty =
     DependencyProperty.Register("Title", typeof(String), typeof(MenuItem));


    public string Title
    {
        get { return (string)GetValue(IconProperty); }
        set { SetValue(IconProperty, value); }
    }

我的 MainWindow 是空的,除了对该控件和 ResourceDictionary 的引用。在后面的MainWindow代码中,我在构造函数中设置了DataContext。

   <Window x:Class="AppUi.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:loc="clr-namespace:AppUi.Control"
    Title="">
     //set up to Resource Dictionary - all binding and styling works fine :)
    <loc:MenuItem Icon="{Binding MailIcon}" Title="{Binding MailTitle}"></loc:MenuItem>

在 MainWindow 的 ModelView 中,我有以下 2 个属性

    private Image_mailIcon;
    public Image MailIcon{
          //inotifyproperty implementation 
    }

    private string _mailTitle;
    public string MailTitle{
          //inotifyproperty implementation 
    }

我的问题是,在 UserControl 中,我该如何进行绑定?由于它是 MainWindow 中的用户控件,并且 MainWindow 已经有一个 datacontext,我认为 UserControl 将从父级继承 DataContext(根据我的阅读)。

那么,在我的 UserControl XAML 中,我应该绑定到 MainWindow 的代码隐藏属性还是绑定到 ViewModel 属性?

换句话说,我的 UserControl 应该是

<Grid>
    <Image Source="{Binding MailIcon}"></Image>
    <TextBlock Text="{Binding MailTitle}"></TextBlock>
</Grid>

<Grid>
    <Image Source="{Binding Icon}"></Image>
    <TextBlock Text="{Binding Title}"></TextBlock>
</Grid>

或者,因为我使用的是 DataContext 并且 UserControl 继承,我什至需要依赖属性吗?

【问题讨论】:

    标签: wpf xaml mvvm user-controls


    【解决方案1】:

    您通常不想覆盖通过可视化树传递的DataContext,因此您可以在UserControl 中使用ElementNameRelativeSource 绑定来更改绑定上下文。实现这一点的最简单方法是给UserControl 一些名称并使用它ElementName 绑定

    <UserControl ... x:Name="myUserControl">
        <!-- ... -->
        <Grid>
            <Image Source="{Binding Icon, ElementName=myUserControl}"/>
            <TextBlock Text="{Binding Title, ElementName=myUserControl}"/>
        </Grid>
        <!-- ... -->
    </UserControl>
    

    这种方式绑定是DataContext 独立的。您还可以创建UserControl,假设它始终仅适用于特定类型的DataContext,然后您只需使用该视图模型类型中的Path,然后DataContext 中的UserControl 必须始终位于视图中它设计的模型(主要通过可视化树继承)

    <UserControl ...>
        <!-- ... -->
        <Grid>
            <Image Source="{Binding MailIcon}"/>
            <TextBlock Text="{Binding MailTitle}"/>
        </Grid>
        <!-- ... -->
    </UserControl>
    

    例如,我还将Icon 属性的类型从Image 更改为ImageSource。您的UserControl 中已经有Image 控件,而您只想绑定它的Source

    【讨论】:

    • 这取决于您的方法。检查我的答案的更新。您可以控制显示一些文本和一些图标,也可以控制显示特定的ViewmModel.MailIconViewmModel.MailTitle
    • 很抱歉,我不能给出超过 +1 的答案并标记为答案...这太棒了,因为这意味着(如果我没明白)我可以将 UserControl 排除在外项目并将其转储到其他东西中!因为它只查看它自己的 DataContext(或它自己的可视化树)
    【解决方案2】:

    在 UserControl 中,我如何进行绑定? ... UserControl 将从父级继承 DataContext

    没错,UserControl 将从父 Window 继承 DataContext。因此,您可以将数据从 UserControl 直接绑定到父 Window.DataContext。请注意,您将绑定到任何已设置为 DataContext 的对象,无论是背后的代码还是单独的视图模型类。

    但是,在这种情况下,您没有将数据绑定到父对象的 DataContext 对象...您还有其他选择。您可以使用RelativeSource Binding 将数据绑定到您自己的UserControl DependencyPropertys,如下所示:

    <TextBlock Text="{Binding Title, RelativeSource={RelativeSource 
        AncestorType={x:Type YourPrefix:YourUserControl}}}" />
    

    您还可以命名您的 UserControl 并引用其属性,如下所示:

    <TextBlock Text="{Binding Title, ElementName=YourUserControlName}" />
    

    虽然这个例子看起来更简洁,但不要忽视第一个例子,因为RelativeSource 是一个有用且强大的朋友。

    我应该绑定到 MainWindow 的 Code Behind 属性还是绑定到 ViewModel 属性?

    这是您的选择...您想要或需要将数据绑定到什么?您只需要知道直接数据绑定将使用自动设置的DataContext 值,因此如果您不想使用它,那么您可以为Binding 指定不同的数据源,如上所示。

    最后,关于是否需要使用DependencyPropertys...您只需要声明它们如果您正在开发需要提供数据绑定能力的UserControl

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-12
      • 2018-01-23
      • 1970-01-01
      • 1970-01-01
      • 2012-11-23
      • 1970-01-01
      相关资源
      最近更新 更多