How to pass the value of 'bound' to a dependency property

My application has MainWindow. Inside this there is 1 control, ListBox , binding to the MainWindowViewModel property. This property is a UserControl of type CriteriaVm

CriteriaVm has one string property MyString

Inside the criteria view, I have the following code

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

As you can see, I bind MyString in 2 places. Binding in Expander works fine, i.e. in vm: PropertiesVm is not used (which uses Dependency Properites). In the output window

The following error is displayed:

System.Windows.Data error: 2: Cannot find a FrameworkElement or FrameworkContentElement control for the target element. BindingExpression: Path = MyString; DataItem = NULL; the target element is "PropertiesVm" (HashCode = 5991653); target is "ThresholdName" (type "String")

OK, the error message tells me that he is looking for MyString in ProperitesVm ... I have to look for MyString in CriteriaVm. This means that I need to use a RelativeSource, which, it seems to me, is above level 1 and of type UserControl. So I updated:

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

I get a slightly different problem, but it seems that the same basic error exists

Error System.Windows.Data: 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 "Properties VM" (HashCode = 24649639); target is "ThresholdName" (type "String")

Currently, PropertiesVm has only dependency properties, PropertiesView is just an empty grid. This means that I can handle this error first and worry about the next binding step later.

I do not understand why I am getting an error message or what I am doing wrong. I can happily provide more code if necessary. The project at this stage is very early, as such, a minimal code.

+5
source share
3 answers

The answer was in the message!

System.Windows.Data error: 2: Cannot find a FrameworkElement or FrameworkContentElement control for the target element. BindingExpression: Path = MyString; DataItem = NULL; the target element is "PropertiesVm" (HashCode = 5991653); target is "ThresholdName" (type "String")

From what I understood, because my UserControl inherited DependencyObject, not UserControl, it was not a UIElement ...

So I had to move the dependency properties into the code name of my view, which allowed the two-way binding to work, but kept the datacontext of my ViewModel in the ViewModel.

+1
source

I expect the view to look like this:

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

The code for the view model will not change much from what you showed:

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

You do not quite understand what "MyStringValue" is, so I expect this to be a normal MainWindow property. MainWindow will instantiate your control by setting "ThresholdName" to this property "MyStringValue":

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

Finally, your MainWindow code will look like this:

 public string MyStringValue { get; set; } public MainWindow() { InitializeComponent(); DataContext = this; MyStringValue = "dog"; } 
+1
source

If you changed the inheritance from DependencyObject to FrameworkElement, this should work.

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

Anyway, have you tried the Attached property?

I think it looks anyway.

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

+1
source

Source: https://habr.com/ru/post/1234380/


All Articles