Targeting Custom Property with Multi Bindings in Silverlight
I'm trying to use WPF MultiBinding to target a custom property I defined on my UserControl. I'm not having any luck. All of the examples that I've seen target built-in .Net properties (Text, ItemSource, IsEnabled). I'm wondering if you can target a custom property. Please help.
///
public partial class ActivityStatusDisplay : UserControl
{
public ActivityStatusDisplay()
{
InitializeComponent();
}
/// <summary>
/// Gets or sets the value for the read/write property named
/// Status.
///
/// </summary>
public TaskStatuses Status
{
get
{
return (TaskStatuses)GetValue(StatusProperty);
}
set
{
SetValue(StatusProperty, value);
UpdateForStatus(value);
开发者_Python百科 }
}
public static readonly DependencyProperty StatusProperty = DependencyProperty.
Register("Status", typeof(TaskStatuses), typeof(ActivityStatusDisplay), null);
with the XAML for binding looking like one of these:
<my:DataGrid ItemsSource="{Binding PatientTaskCollection}">
<my:DataGrid.Columns>
<my:DataGridTemplateColumn Header="Status" Width="Auto">
<my:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<my1:ActivityStatusDisplay Margin="3">
<mb:BindingUtil.MultiBindings>
<mb:MultiBindings>
<mb:MultiBinding TargetProperty="Status" Converter="{StaticResource StatusConverter}">
<mb:MultiBinding.Bindings>
<mb:BindingCollection>
<Binding Path="RecoveryTaskStatusID"/>
<Binding Path="Due"/>
</mb:BindingCollection>
</mb:MultiBinding.Bindings>
</mb:MultiBinding>
</mb:MultiBindings>
</mb:BindingUtil.MultiBindings>
</my1:ActivityStatusDisplay>
or something like:
<my:DataGrid ItemsSource="{Binding PatientTaskCollection}">
<my:DataGrid.Columns>
<my:DataGridTemplateColumn Header="Status" Width="Auto">
<my:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<my1:ActivityStatusDisplay Margin="3">
<my1:ActivityStatusDisplay.Status>
<mb:MultiBinding Converter="{StaticResource StatusConverter}">
<Binding Path="RecoveryTaskStatusID"/>
<Binding Path="Due"/>
</mb:MultiBinding>
</my1:ActivityStatusDisplay.Status>
You problem is that you are assuming the "setter" method for the Status
property gets called when the binding changes its value. This is doesn't happen. Binding calls the SetValue
method directly. Hence your call to UpdateForStatus
doesn't occur when value is modified as a result of binding.
Here is how your dependency property should look, (I'll assume TaskStatuses
is an enum type)
public TaskStatuses Status
{
get { return (TaskStatuses)GetValue(StatusProperty); }
set { SetValue(StatusProperty, value); }
}
public static readonly DependencyProperty StatusProperty =
DependencyProperty.Register(
"Status",
typeof(TaskStatuses),
typeof(ActivityStatusDisplay),
new PropertyMetaData(TaskStatuses.Default, OnStatusPropertyChanged));
private static void OnStatusPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ActivityStatusDisplay source = (ActivityStatusDisplay)d;
TaskStatuses value = (TaskStatuses)e.NewValue;
source.UpdateForStatus(value);
}
Using the PropertyMetaData
parameter of the Register
method we can specify the default value this property should have and a static callback method to call whenever the value of the dependency property is changed. Its from this callback method that you would want to call your UpdateForStatus
method.
精彩评论