如何将 'bound' 值传递给依赖项 属性
How to pass a 'bound' value to a dependency property
我的应用程序有一个主窗口。其中,有 1 个控件,一个 ListBox
,绑定到 MainWindowViewModel 的 属性。此 属性 是 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>
如您所见,我在两个地方绑定了 MyString。 Expander 中的绑定工作正常,vm:PropertiesVm 中的绑定没有(使用 Dependency Properites)。输出 window
中显示以下错误
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=MyString; DataItem=null; target element is 'PropertiesVm' (HashCode=5991653); target property is 'ThresholdName' (type 'String')
好的,错误消息告诉我它正在 ProperitesVm 中寻找 MyString ...我应该在 CriteriaVm 中寻找 MyString。这意味着我需要使用我认为的 RelativeSource,它向上一级并且类型为 UserControl。所以我更新为:
<vm:PropertiesVm ThresholdName="{Binding Path=MyString, RelativeSource={RelativeSource AncestorLevel=1,AncestorType=UserControl,Mode=FindAncestor}}" />
我遇到了一个稍微不同的问题,但似乎存在相同的潜在故障
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.UserControl', AncestorLevel='1''. BindingExpression:Path=MyString; DataItem=null; target element is 'PropertiesVm' (HashCode=24649639); target property is 'ThresholdName' (type 'String')
目前,PropertiesVm 只有依赖属性,PropertiesView 只是一个空的网格。这样我就可以先解决这个错误,然后再考虑下一阶段的绑定。
我不明白为什么我会收到错误消息或我做错了什么。
如果需要,我可以很乐意提供更多代码。这个阶段的项目还很早,代码最少。
我希望视图看起来像这样:
<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";
}
答案在消息中!
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=MyString; DataItem=null; target element is 'PropertiesVm' (HashCode=5991653); target property is 'ThresholdName' (type 'String')
据我了解,因为我的 UserControl 继承了 DependencyObject 而不是 UserControl,所以它不是 UIElement...
因此,我不得不将依赖属性移动到我的视图的代码隐藏,这允许两种方式绑定工作,但将我的 ViewModel 的数据上下文保留在 ViewModel 中。
如果您将继承从 DependencyObject 更改为 FrameworkElement,这应该有效。
<vm:PropertiesVm DataContext="{Binding}" ThresholdName="{Binding MyString}" />
无论如何,你试过附上属性吗?
我想这个在某种程度上是相似的。
我的应用程序有一个主窗口。其中,有 1 个控件,一个 ListBox
,绑定到 MainWindowViewModel 的 属性。此 属性 是 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>
如您所见,我在两个地方绑定了 MyString。 Expander 中的绑定工作正常,vm:PropertiesVm 中的绑定没有(使用 Dependency Properites)。输出 window
中显示以下错误System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=MyString; DataItem=null; target element is 'PropertiesVm' (HashCode=5991653); target property is 'ThresholdName' (type 'String')
好的,错误消息告诉我它正在 ProperitesVm 中寻找 MyString ...我应该在 CriteriaVm 中寻找 MyString。这意味着我需要使用我认为的 RelativeSource,它向上一级并且类型为 UserControl。所以我更新为:
<vm:PropertiesVm ThresholdName="{Binding Path=MyString, RelativeSource={RelativeSource AncestorLevel=1,AncestorType=UserControl,Mode=FindAncestor}}" />
我遇到了一个稍微不同的问题,但似乎存在相同的潜在故障
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.UserControl', AncestorLevel='1''. BindingExpression:Path=MyString; DataItem=null; target element is 'PropertiesVm' (HashCode=24649639); target property is 'ThresholdName' (type 'String')
目前,PropertiesVm 只有依赖属性,PropertiesView 只是一个空的网格。这样我就可以先解决这个错误,然后再考虑下一阶段的绑定。
我不明白为什么我会收到错误消息或我做错了什么。 如果需要,我可以很乐意提供更多代码。这个阶段的项目还很早,代码最少。
我希望视图看起来像这样:
<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";
}
答案在消息中!
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=MyString; DataItem=null; target element is 'PropertiesVm' (HashCode=5991653); target property is 'ThresholdName' (type 'String')
据我了解,因为我的 UserControl 继承了 DependencyObject 而不是 UserControl,所以它不是 UIElement...
因此,我不得不将依赖属性移动到我的视图的代码隐藏,这允许两种方式绑定工作,但将我的 ViewModel 的数据上下文保留在 ViewModel 中。
如果您将继承从 DependencyObject 更改为 FrameworkElement,这应该有效。
<vm:PropertiesVm DataContext="{Binding}" ThresholdName="{Binding MyString}" />
无论如何,你试过附上属性吗?
我想这个在某种程度上是相似的。