Binding Objects Defined by Encoding

I have some object that is created in the code behind, for example, XAML is called window.xaml and inside window.xaml.cs

protected Dictionary<string, myClass> myDictionary; 

How to associate this object with, for example, a list view using only XAML markup?

Update:

(This is exactly in my test code):

 <Window x:Class="QuizBee.Host.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="{Binding windowname}" Height="300" Width="300" DataContext="{Binding RelativeSource={RelativeSource Self}}"> <Grid> </Grid> </Window> 

And in codebehind

 public partial class Window1 : Window { public const string windowname = "ABCDEFG"; public Window1() { InitializeComponent(); } } 

Suppose the name should become "ABCDEFG" correct? but he shows nothing.

+72
c # wpf binding
Nov 10 '09 at 2:39
source share
10 answers

You can set a DataContext for your control, form, etc. So:

 DataContext="{Binding RelativeSource={RelativeSource Self}}" 

Explanation

The data context set to the above value must be executed by any element that "owns" the code behind - therefore, for a window, you must set it in the window declaration.

I have an example of working with this code:

 <Window x:Class="MyClass" Title="{Binding windowname}" DataContext="{Binding RelativeSource={RelativeSource Self}}" Height="470" Width="626"> 

The DataContext set at this level is then inherited by any element in the window (unless you explicitly change it for the child), so after setting the DataContext for the window, you can simply bind directly to the CodeBehind property from any control in the window.

+87
Nov 10 '09 at 2:47
source share

It is much easier to do there. You can assign a name to your window or UserControl, and then bind ElementName.

Window1.xaml

 <Window x:Class="QuizBee.Host.Window1" x:Name="Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <ListView ItemsSource="{Binding ElementName=Window1, Path=myDictionary}" /> </Window> 

Window1.xaml.cs

 public partial class Window1:Window { // the property must be public, and it must have a getter & setter public Dictionary<string, myClass> myDictionary { get; set; } public Window1() { // define the dictionary items in the constructor // do the defining BEFORE the InitializeComponent(); myDictionary = new Dictionary<string, myClass>() { {"item 1", new myClass(1)}, {"item 2", new myClass(2)}, {"item 3", new myClass(3)}, {"item 4", new myClass(4)}, {"item 5", new myClass(5)}, }; InitializeComponent(); } } 
+109
May 16 '11 at 20:07
source share

While Guy's answer is correct (and probably suitable for 9 out of 10 cases), it is worth noting that if you try to do this from a control that already has its DataContext installed, then you will reset it when you set the DataContext to yourself:

 DataContext="{Binding RelativeSource={RelativeSource Self}}" 

This, of course, will break existing bindings.

If so, you should set the RelativeSource for the control you are trying to bind, not its parent.

i.e. to bind to UserControl properties:

 Binding Path=PropertyName, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}} 

Given how difficult it is now to see what happens with data binding, you should keep this in mind even if you find that setting RelativeSource={RelativeSource Self} is currently working :)

+22
May 11 '11 at 15:09
source share

A bit more clarification: Property without 'get', 'set' cannot be bound

I look at the case as well as the question about it. And I must have the following things for the binding to work correctly:

 //(1) Declare a property with 'get','set' in code behind public partial class my_class:Window { public String My_Property { get; set; } ... //(2) Initialise the property in constructor of code behind public partial class my_class:Window { ... public my_class() { My_Property = "my-string-value"; InitializeComponent(); } //(3) Set data context in window xaml and specify a binding <Window ... DataContext="{Binding RelativeSource={RelativeSource Self}}"> <TextBlock Text="{Binding My_Property}"/> </Window> 
+4
Sep 30 '12 at 6:21
source share

Define a converter:

 public class RowIndexConverter : IValueConverter { public object Convert( object value, Type targetType, object parameter, CultureInfo culture ) { var row = (IDictionary<string, object>) value; var key = (string) parameter; return row.Keys.Contains( key ) ? row[ key ] : null; } public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture ) { throw new NotImplementedException( ); } } 

Bind to a custom dictionary definition. There are many overrides that I skipped, but the indexer is important because it emits an event of a changed property when the value changes. This is necessary to bind the source to the target.

 public class BindableRow : INotifyPropertyChanged, IDictionary<string, object> { private Dictionary<string, object> _data = new Dictionary<string, object>( ); public object Dummy // Provides a dummy property for the column to bind to { get { return this; } set { var o = value; } } public object this[ string index ] { get { return _data[ index ]; } set { _data[ index ] = value; InvokePropertyChanged( new PropertyChangedEventArgs( "Dummy" ) ); // Trigger update } } } 

Use your converter in your .xaml file. First contact him:

 <UserControl.Resources> <ViewModelHelpers:RowIndexConverter x:Key="RowIndexConverter"/> </UserControl.Resources> 

Then, for example, if your dictionary has an entry where the key is "Name", and then bind to it: use

 <TextBlock Text="{Binding Dummy, Converter={StaticResource RowIndexConverter}, ConverterParameter=Name}"> 
+1
Nov 10 '09 at 3:07
source share

Make your windowname resource a dependent property and save the rest.

+1
Nov 10 '09 at 7:42
source share

In your code behind, set the DataContext window to the dictionary. In your XAML you can write:

 <ListView ItemsSource="{Binding}" /> 

This will associate the ListView with the dictionary.

For more complex scenarios, this will be a subset of the methods underlying MVVM .

0
Nov 10 '09 at 2:44
source share

One way would be to create an ObservableCollection (System.Collections.ObjectModel) and have the dictionary data in it. You can then bind the ObservableCollection to your ListBox.

In your XAML you should have something like this:

 <ListBox ItemsSource="{Binding Path=Name_of_your_ObservableCollection" /> 
0
Nov 10 '09 at 2:46
source share

I had the same problem, but mine was not because I was setting a local variable ... I was in a child window and I needed to set the relative DataContext that I just added to Window XAML.

 <Window x:Class="Log4Net_Viewer.LogItemWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" DataContext="{Binding RelativeSource={RelativeSource Self}}" Title="LogItemWindow" Height="397" Width="572"> 
0
12 Oct '11 at 18:39
source share

You can try x: Background Trick

 <Window ... x:Name="myWindow"><ListBox ItemsSource="{Binding Items, Source={x:Reference myWindow}}" /></Window> 
0
May 22 '18 at 9:50
source share



All Articles