none
Automatically update when Property changed

    Question

  • Hi,

     

    I want to solve a update-problem. I have a ListBox with some objects. I override the ToString-method to display some important properties in the list and I have a TextBox which shows the (same) properties of the SelectedItem of the ListBox. I use Binding to bind the Text property of the TextBox with the SelectedItem property of the ListBox.

     

    I expected, when I change some properties of an object, that the ListBox wouldn't change the display of the changed object and the TextBox, too.

     

    But what do I have to do, that when I change a property,  the ListBox updates its items (because the changed property is within the overriden ToString() method) and the TextBox updates its Text, which shows some changed properties, too?

     

    I found out, that I can use for updating the TextBox:

    textBox1.GetBindingExpression(TextBox.TextProperty).UpdateTarget();

     

    But when I try the same for the ListBox:

    listBox1.GetBindingExpression(ListBox.ItemsSourceProperty).UpdateTarget();

    nothing happens (the display of the changed item in the itemlist does not change) <-- where is the mistake?

     

     

    But what I really want is, that the ListBox and the TextBox automatically notify the changing of an element and updates their displays (like binding to an ObservableCollection, the ListBox notifies the changes (adding/removing) of items)

     

    You can download my test application: http://www.andreaheeren.de/BindingTestWpfApplication.zip

     

     

    Thanks for your answer.

     

    P.S. Sorry for my bad english :-)

     

     

     

    Wednesday, March 26, 2008 9:49 AM

Answers

  • Solution is simple — for databinding we need a property:

     

    Code Snippet

    using System;

    using System.ComponentModel;

    namespace BindingTestWpfApplication

    {

    public class MyObject : INotifyPropertyChanged

    {

    int value2 = 0;

    string val = "";

    public MyObject(int v, string s)

    {

    value2 = v;

    val = s;

    }

    public override string ToString()

    {

    return "MyObject: value=" + value2.ToString() + ", val=" + val;

    }

    public string Description

    {

    get { return ToString(); }

    }

    public int Value

    {

    get { return value2; }

    set { value2 = value; OnPropertyChanged(new PropertyChangedEventArgs("Value")); OnPropertyChanged(new PropertyChangedEventArgs("Description")); }

    }

    public string Val

    {

    get { return val; }

    set { val = value; OnPropertyChanged(new PropertyChangedEventArgs("Val")); OnPropertyChanged(new PropertyChangedEventArgs("Description")); }

    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(PropertyChangedEventArgs e)

    {

    if (PropertyChanged != null)

    PropertyChanged(this, e);

    }

    #endregion

    }

    }

     

     

    Code Snippet

    <Window x:Class="BindingTestWpfApplication.Window1"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    Title="Window1" Height="403" Width="774">

    <Grid>

    <ListBox HorizontalAlignment="Left" Margin="232,28,0,107" Name="listBox1" Width="143"

    DisplayMemberPath="Description"

    ItemsSource="{Binding ElementName=listBox2, Path=SelectedItem.TheList}"/>

    <Grid Margin="403,38,0,0" Name="grid1" Height="143" VerticalAlignment="Top" HorizontalAlignment="Left" Width="218">

    <TextBox Height="23" Margin="18,18,14,0" Name="textBox1" VerticalAlignment="Top"

    Text="{Binding ElementName=listBox1, Path=SelectedItem.Description}"/>

    </Grid>

    <ListBox HorizontalAlignment="Left" Margin="24,28,0,102" Name="listBox2" Width="120" />

    <Button Height="23" HorizontalAlignment="Right" Margin="0,0,224,68" Name="button1" VerticalAlignment="Bottom" Width="75" Click="button1_Click">Button</Button>

    </Grid>

    </Window>

     

     

     

    Wednesday, March 26, 2008 2:21 PM

All replies

  • Solution is simple — for databinding we need a property:

     

    Code Snippet

    using System;

    using System.ComponentModel;

    namespace BindingTestWpfApplication

    {

    public class MyObject : INotifyPropertyChanged

    {

    int value2 = 0;

    string val = "";

    public MyObject(int v, string s)

    {

    value2 = v;

    val = s;

    }

    public override string ToString()

    {

    return "MyObject: value=" + value2.ToString() + ", val=" + val;

    }

    public string Description

    {

    get { return ToString(); }

    }

    public int Value

    {

    get { return value2; }

    set { value2 = value; OnPropertyChanged(new PropertyChangedEventArgs("Value")); OnPropertyChanged(new PropertyChangedEventArgs("Description")); }

    }

    public string Val

    {

    get { return val; }

    set { val = value; OnPropertyChanged(new PropertyChangedEventArgs("Val")); OnPropertyChanged(new PropertyChangedEventArgs("Description")); }

    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(PropertyChangedEventArgs e)

    {

    if (PropertyChanged != null)

    PropertyChanged(this, e);

    }

    #endregion

    }

    }

     

     

    Code Snippet

    <Window x:Class="BindingTestWpfApplication.Window1"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    Title="Window1" Height="403" Width="774">

    <Grid>

    <ListBox HorizontalAlignment="Left" Margin="232,28,0,107" Name="listBox1" Width="143"

    DisplayMemberPath="Description"

    ItemsSource="{Binding ElementName=listBox2, Path=SelectedItem.TheList}"/>

    <Grid Margin="403,38,0,0" Name="grid1" Height="143" VerticalAlignment="Top" HorizontalAlignment="Left" Width="218">

    <TextBox Height="23" Margin="18,18,14,0" Name="textBox1" VerticalAlignment="Top"

    Text="{Binding ElementName=listBox1, Path=SelectedItem.Description}"/>

    </Grid>

    <ListBox HorizontalAlignment="Left" Margin="24,28,0,102" Name="listBox2" Width="120" />

    <Button Height="23" HorizontalAlignment="Right" Margin="0,0,224,68" Name="button1" VerticalAlignment="Bottom" Width="75" Click="button1_Click">Button</Button>

    </Grid>

    </Window>

     

     

     

    Wednesday, March 26, 2008 2:21 PM
  • Thanks. It works. As you see in my sample source I was close to the solution ;-)  But it was the Description-property and the OnPropertyChanged(new PropertyChangedEventArgs("Description")); that makes it work.

    I found out, that I don't have to use OnPropertyChanged(new PropertyChangedEventArgs("Value")); and OnPropertyChanged(new PropertyChangedEventArgs("Val")); .

     

    But what I have to add, was the BindingMode OneWay to the TextBox-Binding because the Description-property has no (and needs no) setter.

     

    Thanks!

    Thursday, March 27, 2008 7:45 AM