2010-05-31 82 views
2

使用WPF,我想在Text属性的Text属性的绑定内应用转换器。
单个文本框下面的工作:WPF - 将转换器应用于所有文本框

<TextBox Style="{StaticResource TextBoxStyleBase2}" 
          Text="{Binding Text, Converter={StaticResource MyConverter}}"> 
        </TextBox> 

然而,我们的文本框采用的是风格,控制模板,看起来像这样:

<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> 

我如何申请使用该模板我的转换器? 谢谢!

回答

2

试图修改从ControlTemplateTextBox属性将是混乱的,所以我建议你在Style而不是ControlTemplate如果在所有可能做到这一点。我将首先解释如何使用Style来解决该问题,然后解释如何在必要时使用该技术以便在ControlTemplate中使用。

你需要做的是创造一个附加属性,可以这样使用:

<Style x:Name="TextBoxStyleBase2" TargetType="TextBox"> 
    <Setter Property="local:ConverterInstaller.TextPropetyConverter" 
      Value="{StaticResource MyConverter}" /> 
    ... 
</Style> 

ConverterInstaller类有一个简单的附加属性,安装转换器转换成最初设定的TextBox任何Binding

这里
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); 
      })); 
     } 
    }); 
} 

唯一的复杂性是:

  • 使用Dispatcher.BeginInvoke确保绑定更新发生在XAML完成加载并应用所有样式之后,并且
  • 需要将绑定属性复制到新的绑定中以更改转换器,因为原始绑定是密封的

为了这个属性附加到控件模板中的元素,而不是在风格上做的,只是用传递到PropertyChangedCallback原来的对象相同的代码投var element = (FrameworkElement)obj;和Dispatcher.BeginInvoke行动的实际文本框内与var box = (TextBox)element.TemplatedParent;发现

+0

非常感谢!这很好。我只需要修改新绑定的副本,因为Source和RelativeSource不能同时设置(即使它们被设置为NULL)。所以我在分配它们之前添加了一些检查。如果为NULL,我不设置属性。 – joerage 2010-06-07 17:08:12

+0

感谢您的反馈。我已经更新了我的答案来做同样的事情。 – 2010-06-08 22:03:53

相关问题