我看到有人说WPF可以将“自定义类型描述符”用于“更改通知”。
我知道如何进行变更通知的方法是:
object.GetBindingExpression(Bound.property).UpdateTarget();
或者让我的对象实现
INotifiyPropertyChanged
。我看到一些评论说“自定义类型描述符”也可以工作,但是没有人提供有关其工作原理的好例子。我现在正在要求该示例(IE是WPF数据绑定(bind)和通过自定义类型描述符进行更新的一个很好的示例。)
最佳答案
这是一个非常简单的示例。
Window1.xaml :
<Window x:Class="CTDExample.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>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock>Name:</TextBlock>
<TextBox Grid.Column="1" Text="{Binding Name}"/>
<TextBlock Grid.Row="1">Age:</TextBlock>
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Age}"/>
<TextBlock Grid.Row="2" Grid.ColumnSpan="2">
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} is {1} years old.">
<Binding Path="Name"/>
<Binding Path="Age"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</Grid>
</Window>
Window1.xaml.cs :
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows;
namespace CTDExample
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
var ctd = new CTD();
ctd.AddProperty("Name");
ctd.AddProperty("Age");
DataContext = ctd;
}
}
public class CTD : CustomTypeDescriptor
{
private static readonly ICollection<PropertyDescriptor> _propertyDescriptors = new List<PropertyDescriptor>();
public void AddProperty(string name)
{
_propertyDescriptors.Add(new MyPropertyDescriptor(name));
}
public override PropertyDescriptorCollection GetProperties()
{
return new PropertyDescriptorCollection(_propertyDescriptors.ToArray());
}
public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
return GetProperties();
}
public override EventDescriptorCollection GetEvents()
{
return null;
}
public override EventDescriptorCollection GetEvents(Attribute[] attributes)
{
return null;
}
}
public class MyPropertyDescriptor : PropertyDescriptor
{
private readonly IDictionary<object, object> _values;
public MyPropertyDescriptor(string name)
: base(name, null)
{
_values = new Dictionary<object, object>();
}
public override bool CanResetValue(object component)
{
throw new NotImplementedException();
}
public override Type ComponentType
{
get { throw new NotImplementedException(); }
}
public override object GetValue(object component)
{
object value = null;
_values.TryGetValue(component, out value);
return value;
}
public override bool IsReadOnly
{
get { return false; }
}
public override Type PropertyType
{
get { return typeof(object); }
}
public override void ResetValue(object component)
{
throw new NotImplementedException();
}
public override void SetValue(object component, object value)
{
var oldValue = GetValue(component);
if (oldValue != value)
{
_values[component] = value;
OnValueChanged(component, new PropertyChangedEventArgs(base.Name));
}
}
public override bool ShouldSerializeValue(object component)
{
throw new NotImplementedException();
}
public override void AddValueChanged(object component, EventHandler handler)
{
// set a breakpoint here to see WPF attaching a value changed handler
base.AddValueChanged(component, handler);
}
}
}
关于c# - WPF数据绑定(bind)- "Custom Type Descriptor"的示例,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1834454/