I am trying to do follow DataBinding
Property -> DependencyProperty -> Property
But i have trouble.
For example,
We have simple class with two properties implements INotifyPropertyChanged:
public class MyClass : INotifyPropertyChanged
{
private string _num1;
public string Num1
{
get { return _num1; }
set
{
_num1 = value;
OnPropertyChanged("Num1");
}
}
private string _num2;
public string Num2
{
get { return _num2; }
set
{
_num2 = value;
OnPropertyChanged("Num2");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string e)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(e));
}
}
And TextBlock declared in xaml:
<TextBlock Name="tb" FontSize="20" Foreground="Red" Text="qwerqwerwqer" />
Now lets trying to bind Num1 to tb.Text:
private MyClass _myClass = new MyClass();
public MainWindow()
{
InitializeComponent();
Binding binding1 = new Binding("Num1")
{
Source = _myClass,
Mode = BindingMode.OneWay
};
Binding binding2 = new Binding("Num2")
{
Source = _myClass,
Mode = BindingMode.TwoWay
};
tb.SetBinding(TextBlock.TextProperty, binding1);
//tb.SetBinding(TextBlock.TextProperty, binding2);
var timer = new Timer(500) {Enabled = true,};
timer.Elapsed += (sender, args) => _myClass.Num1 += "a";
timer.Start();
}
It works well. But if we uncomment this string
tb.SetBinding(TextBlock.TextProperty, binding2);
then TextBlock display nothing. DataBinding doesn’t work! How can i to do what i want?
The problem is that the
SetBindingcall clears out any previous bindings. So when you set a binding toNum2, you are clearing out the binding toNum1. This happens because a dependency property binding cannot have multiple sources- how would it know which one to use? (Of course, this ignores the usage of aMultiBinding, but that’s not going to help you in this scenario).The way you can do this is to make
MyClassaDependencyObjectandNum1andNum2dependency properties. Then you can bindNum2to theTextproperty of theTextBox, andNum2will be updated whenever the text receives an update fromNum1.A picture is worth a thousand words- what you’re trying to do is shown on the left. What you need to do is shown on the right:
alt text http://img339.imageshack.us/img339/448/twosources.png
Decided to try this out to ensure my logic was sound, and indeed it works, but there are some tricks. For starters, here is the new
MyClasscode:Nothing scary here, just replaced your
INotifyPropertyChangedwithDependencyProperty. Now let’s check out the window code-behind:This is where the magic happens: we set up two bindings. The first binds the
TextBlock.TexttoNum1, the second bindsNum2to theTextBlock.Text. Now we have a scenario like the right side of the picture I showed you- a data-binding chain. The other magic is that we cannot update theNum1property on a different thread from the one it was created on- that would create a cross-thread exception. To bypass this, we simply invoke an update onto the UI thread using theDispatcher.Finally, the XAML used for demonstration:
And voila! The finished product:
alt text http://img163.imageshack.us/img163/6114/victorynf.png