我有一个名为TxtBox
的类,其附加属性:
public class TxtBox
{
public static readonly DependencyProperty TypeProperty = DependencyProperty.RegisterAttached(
"Type", typeof (Enums.FieldType), typeof (TextBox), new PropertyMetadata(default(Enums.FieldType),OnTypeChanged));
public static void SetType(DependencyObject element, Enums.FieldType value)
{
element.SetValue(TypeProperty, value);
}
public static Enums.FieldType GetType(DependencyObject element)
{
return (Enums.FieldType) element.GetValue(TypeProperty);
}
private static void OnTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var src = (TextBox) d; //(FrameworkElement)d;
var binding = BindingOperations.GetBinding(src, TextBox.TextProperty);
if (binding != null) //Binding here is always null ?????????
{
binding.Converter = new NumberConverter();
binding.ConverterParameter = e.NewValue;
}
}
}
在MainWindow.xaml:
<Grid Margin="10">
<TextBox Text="{Binding RequestNo}" att:TxtBox.Type="Number" />
<\Grid>
一旦我通过附加属性(Type)设置了文本框控件的类型,我就需要为Converter
分配ConverterParameter
和TextProperty
。当OnTypeChanged
方法触发时,我无法获得绑定,因为它始终为空!
提前致谢:)
答案 0 :(得分:0)
在将Binding应用于“文本”框的“文本”属性之前,正在设置附加属性。您可以通过在Text
的值更改时尝试更新Binding来解决此问题:
private static void OnTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var src = (TextBox)d;
var dpd = DependencyPropertyDescriptor.FromProperty(TextBox.TextProperty, typeof(TextBox));
dpd.AddValueChanged(src, UpdateBindingHandler);
UpdateBinding(src);
}
protected static void UpdateBindingHandler(object sender, EventArgs e)
{
UpdateBinding((TextBox)sender);
}
private static void UpdateBinding(TextBox tbox)
{
var binding = BindingOperations.GetBinding(tbox, TextBox.TextProperty);
if (binding != null)
{
binding.Converter = new NumberConverter();
binding.ConverterParameter = GetType(tbox);
var dpd = DependencyPropertyDescriptor.FromProperty(TextBox.TextProperty, typeof(TextBox));
// Don't do this every time the value changes, only the first time
// it changes after TxtBox.Type has changed.
dpd.RemoveValueChanged(tbox, UpdateBindingHandler);
}
}
当你这样做时,你会发现你的整个设计存在缺陷:一旦使用Binding
,你就无法改变它。它引发了一个例外。
您可以通过创建新绑定,克隆旧绑定的属性以及在其上放置转换器来逃脱。但是,绑定具有很多属性,如果已经有转换器,那么您需要将链接转换器替换为保留转换器的转换器。
我不确定此功能是否会成功。
答案 1 :(得分:0)
最后,我得到了解决方案,我改变了设计,因为Peter Duniho先生建议我写一个标记扩展来代替{Binding}
public class TextBoxTypeExtension:MarkupExtension
{
private readonly Binding _binding;
public TextBoxTypeExtension(Binding binding,Enums.FieldType type)
{
_binding = binding;
_binding.Converter = new NumberConverter();
_binding.ConverterParameter = type;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return _binding.ProvideValue(serviceProvider);
}
}
在MainWindow.xaml:
<TextBox MaxLength="10" Grid.Row="1" Grid.Column="1"
Text="{extension:TextBoxType {Binding Request.RequestNo},Number}"/>