Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding a property from a class to XAML directly

Tags:

c#

mvvm

wpf

I was curious as I was learning more on binding with WPF do you HAVE TO set the data context to simply set the {binding path=} of a single property? I was just curious as I was learning from the MVVM example of code behind and it appears I have a situation I want to bind to something not in the data context of the ViewModel and I would prefer an intermediary class over code behind to reference in a binding. So could I have yet another class I reference for either a second datacontext or something similar? Or could I set a resource key and reference the class somehow? I ultimately want to access a property in a separate class if possible.

EG:

<Window x:Class="WPFTestBinding.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:da="clr-namespace:WPFTestBinding.DataAccess"
        xmlns:main="clr-namespace:WPFTestBinding"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <StackPanel>
            <Label Content="Here we go: "/>
            <TextBox x:Name="testtext" />
            <Label Height="50" />
            <!-- CODE BELOW WILL NOT WORK -->
            <TextBox Text="{Binding Path=TestID}" x:Name="testtext2" />
        </StackPanel>
    </Grid>
</Window>

I know I can set the value of a TextBox in code behind and it works in the example of a property but it will not for the binding. Is there a way to do simple binding on the fly for properties from classes? I have not found a simple example that does this and I was searching online and while learning binding most examples are either very intense sets of settings data contexts or very simple static resource examples. I was just curious if you could use the {Binding Path=} and extend some other property on the fly to just get the code in the class.

Rest of code is pretty simple:

namespace WPFTestBinding.DataAccess
{
    class Test
    {
        public string TestID { get { return "This is my test"; } }
    }
}

 public partial class MainWindow : Window
    {    
        public MainWindow()
        {
           InitializeComponent();

           DataAccess.Test t = new Test();

           testtext.Text = t.TestID;  // code behind works easily
         }
    }
like image 237
djangojazz Avatar asked Jan 07 '13 05:01

djangojazz


3 Answers

You can set the DataContext in Xaml like this:

<Window xmlns:da="clr-namespace:WPFTestBinding.DataAccess">
    <Window.DataContext>
        <da:Test/>
    <Window.DataContext>

    <TextBox Text="{Binding TestID}"/>
</Window>
like image 69
kusi581 Avatar answered Nov 15 '22 17:11

kusi581


Some points to note:

  • The property TestID you are trying to bind is read-only, as it only has get-accessor. Therefore, Binding should be OneWay only.
  • Assigning the DataContext: You can assign the instance holding your model such MainViewModel with ICollection<BaseViewModel> property (which would be having all the derived instances in the collection) or directly the model itself (as in your case). As I have done in code below.

Code

namespace WPFTestBinding.DataAccess
{
    class Test
    {
        public string TestID { get { return "This is my test"; } }
    }
}

public partial class MainWindow : Window
{    
    public MainWindow()
    {
       InitializeComponent();

       DataAccess.Test testInstance = new Test();
       this.DataContext = testInstance;
    }
}

XAML

<TextBox Text="{Binding Path=TestID, Mode=OneWay}" x:Name="txtTestID" />

For more refer:

  • MSDN - Data Binding Overview
  • MSDN - WPF BindingMode
  • Code Project - DataContext-in-WPF
  • SO - What is DataContext for?
  • SO - Difference between Datacontext and ItemSource
like image 32
Harsh Baid Avatar answered Nov 15 '22 17:11

Harsh Baid


The data context is not set. The DataBinding doesn't know where to take TestID from. Here is correct code behind:

namespace WPFTestBinding.DataAccess
{
    class Test
    {
        public string TestID { get { return "This is my test"; } }
    }
}

public partial class MainWindow : Window
{    
    public MainWindow()
    {
       InitializeComponent();
       DataAccess.Test t = new Test();

       DataContext = t;           
    }
}
like image 38
Sergii Vashchyshchuk Avatar answered Nov 15 '22 15:11

Sergii Vashchyshchuk