【问题标题】:How to pass a 'bound' value to a dependency property如何将“绑定”值传递给依赖属性
【发布时间】:2015-10-23 14:48:42
【问题描述】:

我的应用程序有一个主窗口。其中有 1 个控件,一个 ListBox,绑定到 MainWindowViewModel 的一个属性。该属性是一个 UserControl,类型为 CriteriaVm

CriteriaVm 有一个名为 MyString 的字符串属性

在标准视图中,我有以下代码

<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>

如您所见,我在 2 个地方绑定了 MyString。 Expander 中的绑定工作正常,vm:PropertiesVm 中的绑定没有(它使用依赖属性)。输出窗口中显示以下错误

System.Windows.Data 错误:2:找不到目标元素的管理 FrameworkElement 或 FrameworkContentElement。绑定表达式:路径=我的字符串;数据项=空;目标元素是“PropertiesVm”(HashCode=5991653);目标属性是“阈值名称”(类型“字符串”)

好的,错误消息告诉我它正在 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''的绑定源。绑定表达式:路径=我的字符串;数据项=空;目标元素是“PropertiesVm”(HashCode=24649639);目标属性是“阈值名称”(类型“字符串”)

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

我不明白为什么我会收到错误消息或我做错了什么。 如果需要,我可以很乐意提供更多代码。这个阶段的项目还很早,所以代码最少。

【问题讨论】:

  • 1.将 [BindableAttribute(true)] 属性添加到 ThresholdName 属性

标签: wpf mvvm dependency-properties


【解决方案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); }
    }
}

您并不完全清楚“MyStringValue”是什么,所以我希望它是 MainWindow 的正常属性。 MainWindow 将创建您的控件的实例,将“ThresholdName”设置为此“MyStringValue”属性:

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

最后你的 MainWindow 代码是:

public string MyStringValue { get; set; }

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

【讨论】:

  • 我迷失了你的例子 - 你正在使用 ControlTemplate,基本上覆盖了已经存在的内容。这不是目标:S
【解决方案2】:

如果您将继承从 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

【讨论】:

    【解决方案3】:

    答案在消息中!

    System.Windows.Data 错误:2:找不到目标元素的管理 FrameworkElement 或 FrameworkContentElement。绑定表达式:路径=我的字符串;数据项=空;目标元素是“PropertiesVm”(HashCode=5991653);目标属性是'ThresholdName'(类型'String')

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

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

    【讨论】:

      猜你喜欢
      • 2014-03-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      • 1970-01-01
      • 1970-01-01
      • 2017-08-07
      • 2020-12-22
      • 1970-01-01
      相关资源
      最近更新 更多