如何将“绑定”值传递给依赖项属性

时间:2015-10-23 14:48:42

标签: wpf mvvm dependency-properties

我的应用程序有一个MainWindow。在此范围内,有1个控件,ListBox,绑定到MainWindowViewModel的属性。此属性是UserControl,类型为CriteriaVm

CriteriaVm有一个名为MyString

的字符串属性

在Criteria View中我有以下代码

<UserControl x:Class="CompoundInterests.View.CriteriaView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:vm="clr-namespace:CompoundInterests.ViewModel"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="600">

    <UserControl.Resources>
        <ResourceDictionary Source="../Dictionary.xaml" />
    </UserControl.Resources>
    <Grid>
        <Border>
            <Expander Header="{Binding MyString}" >
                <vm:PropertiesVm ThresholdName="{Binding MyString}" />
            </Expander>
        </Border>
    </Grid>
</UserControl>

正如你所看到的,我在两个地方绑定了MyString。扩展器中的绑定工作正常,vm中的绑定:PropertiesVm没有(使用Dependency Properites)。输出窗口中显示以下错误

  

System.Windows.Data错误:2:找不到目标元素的管理FrameworkElement或FrameworkContentElement。 BindingExpression:路径= MyString中;的DataItem = NULL; target元素是'PropertiesVm'(HashCode = 5991653); target属性是'ThresholdName'(类型'String')

确定错误消息告诉我它在ProperitesVm中寻找MyString ...我应该在CriteriaVm中寻找MyString。这意味着我需要使用RelativeSource,我认为它是1级和UserControl类型。所以我更新到:

<vm:PropertiesVm ThresholdName="{Binding Path=MyString, RelativeSource={RelativeSource AncestorLevel=1,AncestorType=UserControl,Mode=FindAncestor}}" />

我得到一个稍微不同的问题,但看起来好像存在相同的潜在错误

  

System.Windows.Data错误:4:无法找到与引用'RelativeSource FindAncestor绑定的源,AncestorType ='System.Windows.Controls.UserControl',AncestorLevel ='1''。 BindingExpression:路径= MyString中;的DataItem = NULL; target元素是'PropertiesVm'(HashCode = 24649639); target属性是'ThresholdName'(类型'String')

目前,PropertiesVm只有依赖属性,PropertiesView只是一个空网格。这样我就可以先处理这个错误,然后再担心下一个绑定阶段。

我不明白为什么我收到错误消息或者我做错了什么。 如果需要,我可以愉快地提供更多代码。这个阶段的项目很早,因此是最少的代码。

3 个答案:

答案 0 :(得分:1)

我希望视图看起来像这样:

<Style TargetType="{x:Type ns:YourViewModel}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ns:YourViewModel}">
                <Grid>
                    <TextBlock Text="{Binding ThresholdName, 
                               RelativeSource={RelativeSource TemplatedParent}}"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

视图模型代码与您所显示的内容几乎没有变化:

public class YourViewModel: Control
{
    public static readonly DependencyProperty ThreshNameProperty = DependencyProperty.Register("ThresholdName", typeof(string), typeof(PropertiesVm), new PropertyMetadata(string.Empty));

    public string ThresholdName
    {
        get { return GetValue(ThreshNameProperty).ToString(); }
        set { SetValue(ThreshNameProperty, value); }
    }
}

你并不完全清楚&#34; MyStringValue&#34;是的,我希望它是MainWindow的正常属性。 MainWindow会创建一个控件实例,设置&#34; ThresholdName&#34;对此&#34; MyStringValue&#34;属性:

<Grid>
    <ns:YourViewModel ThresholdName="{Binding MyStringValue}"/>
</Grid>

最后你的MainWindow代码是:

public string MyStringValue { get; set; }

public MainWindow()
{
    InitializeComponent();
    DataContext = this;
    MyStringValue = "dog";
}

答案 1 :(得分:1)

答案在信息中!

  

System.Windows.Data错误:2:找不到目标元素的管理FrameworkElement或FrameworkContentElement。 BindingExpression:路径= MyString中;的DataItem = NULL;目标元素是&#39; PropertiesVm&#39; (的HashCode = 5991653);目标属性是'ThresholdName&#39; (键入&#39; String&#39;)

根据我的理解,因为我的UserControl继承了DependencyObject而不是UserControl它不是UIElement ......

因此,我不得不将依赖属性移动到我的View的代码隐藏,这允许双向绑定工作,但在ViewModel中保留了我的ViewModel的datacontext。

答案 2 :(得分:1)

如果您将继承从DependencyObject更改为FrameworkElement,则应该可以。

<vm:PropertiesVm DataContext="{Binding}" ThresholdName="{Binding MyString}" />

无论如何,你有没有试过附属物?

我猜这一个是这样或那样的。

https://social.msdn.microsoft.com/Forums/vstudio/en-US/aff23943-5483-40b2-816b-4ce687bc6bf8/systemwindowsdata-error-2-cannot-find-governing-frameworkelement?forum=wpf