Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding objects defined in code-behind

Tags:

c#

.net

binding

wpf

I have some object that is instantiated in code behind, for instance, the XAML is called window.xaml and within the window.xaml.cs

protected Dictionary<string, myClass> myDictionary;

How can I bind this object to, for example, a list view, using only XAML markups?

Update:

(This is exactly I have 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 title should become "ABCDEFG" right? but it ends up showing nothing.

like image 516
xandy Avatar asked Nov 10 '09 02:11

xandy


People also ask

What is a bind in code?

In computer programming, to bind is to make an association between two or more programming objects or value items for some scope of time and place.

What is code behind in WPF?

Code-behind is a term used to describe the code that is joined with markup-defined objects, when a XAML page is markup-compiled. This topic describes requirements for code-behind as well as an alternative inline code mechanism for code in XAML.

What is the syntax for binding a command to an object?

Binding path syntax. Use the Path property to specify the source value you want to bind to: In the simplest case, the Path property value is the name of the property of the source object to use for the binding, such as Path=PropertyName . Subproperties of a property can be specified by a similar syntax as in C#.


4 Answers

There's a much easier way of doing this. You can assign a Name to your Window or UserControl, and then binding by 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();
    }
}
like image 87
Saad Imran. Avatar answered Oct 18 '22 23:10

Saad Imran.


You can set the DataContext for your control, form, etc. like so:

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

Clarification:

The data context being set to the value above should be done at whatever element "owns" the code behind -- so for a Window, you should set it in the Window declaration.

I have your example 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 then is inherited by any element in the window (unless you explicitly change it for a child element), so after setting the DataContext for the Window you should be able to just do straight binding to CodeBehind properties from any control on the window.

like image 26
Guy Starbuck Avatar answered Oct 19 '22 00:10

Guy Starbuck


While Guy's answer is correct (and probably fits 9 out of 10 cases), it's worth noting that if you are attempting to do this from a control that already has its DataContext set further up the stack, you'll resetting this when you set DataContext back to itself:

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

This will of course then break your existing bindings.

If this is the case, you should set the RelativeSource on the control you are trying to bind, rather than its parent.

i.e. for binding to a UserControl's properties:

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

Given how difficult it can be currently to see what's going on with data binding, it's worth bearing this in mind even if you find that setting RelativeSource={RelativeSource Self} currently works :)

like image 28
CatBusStop Avatar answered Oct 18 '22 22:10

CatBusStop


Just a little more clarification: A property without 'get','set' won't be able to be bound

I'm facing the case just like the asker's case. And I must have the following things in order for the bind to work properly:

//(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>
like image 9
jondinham Avatar answered Oct 19 '22 00:10

jondinham