I've decided to experiment a little with bound dependency properties in view models. For that I've set up a simple test project, consisting of a MainWindow.xaml:
<Window x:Class="MVVM_Test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MVVM_Test"
xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ListBox Margin="6" Grid.RowSpan="2" Name="PART_LISTBOX">
<sys:String>String 1</sys:String>
<sys:String>String 2</sys:String>
<sys:String>String 3</sys:String>
</ListBox>
<StackPanel Name="PART_spViewModel2" Grid.Column="1" Grid.Row="1">
<StackPanel.DataContext>
<local:ViewModel2 BoundString="{Binding ElementName=PART_LISTBOX,
Path=SelectedItem,
diag:PresentationTraceSources.TraceLevel=High}" />
</StackPanel.DataContext>
<TextBox Margin="6" Text="{Binding BoundString}" />
</StackPanel>
</Grid>
</Window>
and backed up by a simple view model object:
public class ViewModel2 : DependencyObject
{
public string BoundString
{
get { return (string)GetValue(BoundStringProperty); }
set { SetValue(BoundStringProperty, value); }
}
// Using a DependencyProperty as the backing store for BoundString.
public static readonly DependencyProperty BoundStringProperty =
DependencyProperty.Register("BoundString", typeof(string), typeof(ViewModel2),
new FrameworkPropertyMetadata(default(string),
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault ));
}
Now I expected the Content of the Textbox to change once I select something within the ListBox. However, when I run the program, it seems the ListBox cannot be found by the DataBinding:
System.Windows.Data Warning: 56 : Created BindingExpression (hash=61931053) for Binding (hash=40205895)
System.Windows.Data Warning: 58 : Path: 'SelectedItem'
System.Windows.Data Warning: 60 : BindingExpression (hash=61931053): Default mode resolved to TwoWay
System.Windows.Data Warning: 61 : BindingExpression (hash=61931053): Default update trigger resolved to PropertyChanged
System.Windows.Data Warning: 62 : BindingExpression (hash=61931053): Attach to MVVM_Test.ViewModel2.BoundString (hash=64815892)
System.Windows.Data Warning: 64 : BindingExpression (hash=61931053): Use Framework mentor
System.Windows.Data Warning: 67 : BindingExpression (hash=61931053): Resolving source
System.Windows.Data Warning: 69 : BindingExpression (hash=61931053): Framework mentor not found
System.Windows.Data Warning: 65 : BindingExpression (hash=61931053): Resolve source deferred
The deferred lookup goes on a little until it hits this point:
System.Windows.Data Warning: 67 : BindingExpression (hash=61931053): Resolving source (last chance)
System.Windows.Data Warning: 69 : BindingExpression (hash=61931053): Framework mentor not found
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=SelectedItem; DataItem=null; target element is 'ViewModel2' (HashCode=64815892); target property is 'BoundString' (type 'String')
If I do the binding the other way round, e.g. from the ListBox.SelectedItem
property towards the ViewModel it works.
<ListBox Margin="6" Grid.RowSpan="2" Name="PART_LISTBOX"
SelectedItem="{Binding ElementName=PART_spViewModel2,
Path=DataContext.BoundString}">
So my guess is that I've not set up the DependencyProperty correctly, but where exactly did I make a mistake?
DependencyProperty
on the view model in the first place and simply could do withNotifyPropertyChanged
properties on the view model in the first place? – Adwaenyth