views:

503

answers:

4

OK... I'm a VB.NET WinForms guy trying to understand WPF and all of its awesomeness. I'm writing a basic app as a learning experience, and have been reading lots of information and watching tutorial videos, but I just can't get off the ground with simple DataBinding, and I know I'm missing some basic concept. As much as I'd love it, I haven't had that "Aha!" moment when reviewing source code yet.

So... In my Window class I defined a custom string Property. When I go into Blend, I try to databind my TextBox's Text to this property, but my Property doesn't show up in Blend as something that available for Binding to.

Can someone tell me what I need to add to my code/XAML below... and most importantly why?

My XAML:

<Window x:Class="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">
    <Grid>
        <TextBox Text="How do I Bind my SomeText property here?"></TextBox>
    </Grid>
</Window>

My Window Code:

Class Window1 

    Private _sometext As String = "Hello World"

    Public Property SomeText() As String
        Get
            Return _sometext
        End Get
        Set(ByVal value As String)
            _sometext = value
        End Set
    End Property

End Class
+6  A: 

Here's how you need to change your XAML (the code is fine).

<Window x:Class="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" 
            DataContext="{Binding RelativeSource={RelativeSource Self}}">    
      <Grid>        
          <TextBox Text="{Binding SomeText}">
          </TextBox>    
      </Grid>
    </Window>

To understand Bindings in WPF, you need to understand the DataContext. Every element has a DataContext property, and any object you put in that property becomes the data source of any bindings which do not have an explicit data source specified. The value of the DataContext is inherited from a parent object (so in this case the TextBox inherits the Grid's DataContext, which inherits the Window's DataContext). Since you want to refer to a property of the window, you need to set the DataContext to point to the Window instance, which is what I do in the DataContext attribute of the Window.

You can also change the data source for individual bindings by using the Source= or RelativeSource= syntax in the {Binding } element.

Samuel Jack
Thank you, I will give this a try.So, about the binding string "{Binding RelativeSource={RelativeSource Self}}"Can this be generated in Blend? Will VS help me generate it with intellisense? Is there any way for me to discover the correct syntax for these things or do I just need to remember it?
B2Ben
I don't think Blend or VS help very much in these cases. If you have Resharper, it does add a bit of intellisense with XAML.
Samuel Jack
I personally like using DataContext much better than using ElementName (like I did in my answer). I only used ElementName to help clarify what the Source is (for learning purposes). DataContext brings some additional complexity to understand ... given that it inherits down the visual tree.
cplotts
+5  A: 
cplotts
+1  A: 

WPF DataBinding is a very powerful feature. I suggest to read some already existing articles on the web, such as

Very helpful to me was also Beatrix Costa's blog on Data Binding.

EFrank
I recommend all of the above resources as well. Bea's blog, in particular, is outstanding on this subject.
cplotts
A: 

Data binding with a CLR property requires an extra step. You have to implement INotifyPropertyChanged and fire the PropertyChanged event whenever that CLR property changes. This won't make it appear in Blend, but you can bind to the property using Text="{Binding SomeText}" and setting the window's DataContext to your object.

There is an alternative. Instead of using .NET data binding, consider Update Controls .NET. It's an open source project that replaces data binding and does not require INotifyPropertyChanged. The great thing about Update Controls is that it can see through intermediate business logic. With INotifyPropertyChanged you have to catch and re-fire events.

Michael L Perry