使用WPF,我想在所有TextBox中的Text属性的绑定中应用转换器 以下适用于单个TextBox:
<TextBox Style="{StaticResource TextBoxStyleBase2}"
Text="{Binding Text, Converter={StaticResource MyConverter}}">
</TextBox>
但是,我们的TextBoxes使用带有控制模板的样式,如下所示:
<Grid>
<Border x:Name="Border"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{StaticResource DefaultCornerRadius}">
<Grid>
<Border BorderThickness="1">
<ScrollViewer x:Name="PART_ContentHost" Margin="0"/>
</Border>
</Grid>
</Border>
</Grid>
如何使用此模板应用转换器? 谢谢!
答案 0 :(得分:2)
任何从TextBox
内部修改ControlTemplate
属性的尝试都会很混乱,因此我建议您尽可能在Style
而不是ControlTemplate
进行修改。我将首先解释如何使用Style
解释如何根据需要调整技术以便在ControlTemplate
中使用。
您需要做的是创建一个可以像这样使用的附加属性:
<Style x:Name="TextBoxStyleBase2" TargetType="TextBox">
<Setter Property="local:ConverterInstaller.TextPropetyConverter"
Value="{StaticResource MyConverter}" />
...
</Style>
ConverterInstaller
类有一个简单的附加属性,可将转换器安装到Binding
上最初设置的任何TextBox
中:
public class ConverterInstaller : DependencyObject
{
public static IValueConverter GetTextPropertyConverter(DependencyObject obj) { return (IValueConverter)obj.GetValue(TextPropertyConverterProperty); }
public static void SetTextPropertyConverter(DependencyObject obj, IValueConverter value) { obj.SetValue(TextPropertyConverterProperty, value); }
public static readonly DependencyProperty TextPropertyConverterProperty = DependencyProperty.RegisterAttached("TextPropertyConverter", typeof(IValueConverter), typeof(Converter), new PropertyMetadata
{
PropertyChangedCallback = (obj, e) =>
{
var box = (TextBox)obj;
box.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
{
var binding = BindingOperations.GetBinding(box, TextBox.TextProperty);
if(binding==null) return;
var newBinding = new Binding
{
Converter = GetTextPropertyConverter(box),
Path = binding.Path,
Mode = binding.Mode,
StringFormat = binding.StringFormat,
}
if(binding.Source!=null) newBinding.Source = binding.Source;
if(binding.RelativeSource!=null) newBinding.RelativeSource = binding.RelativeSource;
if(binding.ElementName!=null) newBinding.ElementName = binding.ElementName;
BindingOperations.SetBinding(box, TextBox.TextProperty, newBinding);
}));
}
});
}
这里唯一的复杂性是:
要将此属性附加到ControlTemplate内部的元素而不是在样式中执行它,除了传递给PropertyChangedCallback的原始对象是强制转换var element = (FrameworkElement)obj;
并且在Dispatcher.BeginInvoke操作内部实际执行时,使用相同的代码使用var box = (TextBox)element.TemplatedParent;