Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to bind code-behind property without setting DataContext?

Tags:

wpf

xaml

As titled, I seen couples of similiar question this or this in SO, but I don't see a solution for it.

I know if I need to bind to the code-beind, I need to set Datacontext = this

But my problem is that my datacontext already binding to my ViewModel, but I want to do some UI manipulation with using Command which is defined in the code-beind.

Is it possbile to bind it in xaml? If so, how?

EDIT: I did tried the follows:

<Window x:Class="WpfApplication3.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300" x:Name="_Root">
<Grid x:Name="hellogrid">
    <TextBlock x:Name="myTextBlock" Text="AAAA"/>
    <Button Margin="82,119,121,120" Name="button2" Content="{Binding Path=Text, ElementName=myTextBlock}"/>
    <Button Margin="82,72,121,0" Name="button3" Content="{Binding Path=MyText, ElementName=_Root}" Height="23" VerticalAlignment="Top" />
</Grid>

And code-behind:

public partial class Window1 : Window
{
    public string MyText { get; set; }

    public Window1()
    {
        InitializeComponent();
        MyText = "ABC";
    }
}

I could see the Button2 shows AAAA, but Button3 shows nothing....

like image 941
King Chan Avatar asked Feb 15 '12 17:02

King Chan


People also ask

What is the use of DataContext in WPF?

There are several ways to specify the binding source object. Using the DataContext property on a parent element is useful when you're binding multiple properties to the same source. However, sometimes it may be more appropriate to specify the binding source on individual binding declarations.

What is binding path?

Binding paths address the different properties and lists in a model and define how a node in the hierarchical data tree can be found.

What is binding source in WPF?

A binding source is usually a property on an object so you need to provide both the data source object and the data source property in your binding XAML. In the above example the ElementName attribute signifies that you want data from another element on the page and the Path signifies the appropriate property.

What is DataContext?

The DataContext is the source of all entities mapped over a database connection. It tracks changes that you made to all retrieved entities and maintains an "identity cache" that guarantees that entities retrieved more than one time are represented by using the same object instance.


2 Answers

EDIT

The best solution IMO is the one posted by @Saad Imran in this SO question...

With this solution all you have to do is name your window and binding to a property in your XAML will be as easy as this {Binding ElementName=MyWindowName, Path=MyText}

So, what you are doing with Content="{Binding Path=MyText, ElementName=_Root}" is exactly right and your Button Content property IS bound to MyText property but the only thing you are missing is change notification (need to implement INotifyPropertyChanged interface for that) so when you set your MyText property to ABC MyText = "ABC"; no change notification is sent...

Easy way to test this is by setting the MyText property explicitly as such:

private string myText = "ABC";
public string MyText
{
   get { return myText; }
   set { myText = value; }
}

or setting it in the constructor before InitializeComponent() is called:

MyText = "ABC";
InitializeComponent();

If you do that you'll notice that your button will have ABC as its content but changes to MyText property will not affect the button content because there is no change notification...

like image 182
Dean Kuga Avatar answered Oct 15 '22 01:10

Dean Kuga


Of course

There are many types of bindings. The most basic one binds to a property on the DataContext, which is usually inherited from a Parent object

<DataTemplate DataType="{x:Type MyModel}">
    <!-- DataContext is object of type MyModel -->
    <local:MyView />
</DataTemplate>

Or

<Window x:Name="MyWindow">
    <!-- DataContext Inherited from Window -->
    <TextBlock Text="{Binding SomeProperty}" /> 
</Window>

where

var SomeObject = new SomeModel();
SomeObject.SomeProperty = "Test";
myWindow.DataContext = SomeObject;

Other binding types include ElementName, where you can specify the target UI element to use as the data source for the binding

<StackPanel>
    <CheckBox x:Name="SomeCheckBox" />
    <TextBlock Text="{Binding ElementName=SomeCheckBox, Path=IsChecked}" />
</StackPanel>

or

<local:MyUserControl x:Name="SomeUserControl">
    <Button Command="{Binding ElementName=SomeUserControl, Path=DataContext.SaveCommand}" />
</local:MyUserControl >

Or RelativeSource, which allows you to find an object relative to the current object to use as a DataSource

<Window Title="Test">
    <TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=Title}" />
</Window>

or

<local:MyUserControl>
    <Button Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:MyUserControl}}, Path=DataContext.SaveCommand}" />
</local:MyUserControl >

And TemplateBinding, which binds is a shortcut to a RelativeSource binding that binds to a templated object

<Button Content="Test">
    <Button.Template>
        <ControlTemplate TargetType="{x:Type Button}">
            <TextBlock Text="{TemplateBinding Content}" />
        </ControlTemplate>
    </Button.Template>
</Button>
like image 35
Rachel Avatar answered Oct 14 '22 23:10

Rachel