Can I change the binding properties in a DataTrigger without knowing the binding itself?

I have a TextBox style that formats a number if the field is not focused, but leaves the number unformatted when it is being edited.

This is the style I want for several text fields, but they all contain different text bindings. The only difference between the regular text installer and the Triggered Text installer is that Triggered has StringFormat=N2 in the binding.

Is there a way to make this style generic, for example, only change the StringFormat property of the bindings in a DataTrigger?

 <TextBox> <TextBox.Style> <Style TargetType="{x:Type TextBox}"> <Setter Property="Text" Value="{Binding SomeValue, StringFormat=N2, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" /> <Style.Triggers> <Trigger Property="IsKeyboardFocusWithin" Value="True"> <Setter Property="Text" Value="{Binding SomeValue, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" /> </Trigger> </Style.Triggers> </Style> </TextBox.Style> </TextBox> 
+8
data-binding styles wpf xaml
source share
5 answers

The only option I see there is to create an attached property for StringFormat and use multiBinding.

Not quite what you wanted, but close enough, I think ...

you have additional information about this (kind of duplicate) question about SO:

Change TextBox Text Binding Options Using a Style

+2
source share

Is there a way to make this style generic, for example, only change the StringFormat property of the bindings in a DataTrigger?

Inherit Style , and the new XAML will be as follows:

  <TextBox> <TextBox.Style> <local:FlyingStyle Binding="{Binding ElementName=This, Path=SomeValue}" StringFormat="F2" /> </TextBox.Style> </TextBox> 

Here is the class ...

 public class FlyingStyle : Style { public FlyingStyle() : base(typeof(TextBox)) { } string _stringFormat; public string StringFormat { get { return _stringFormat; } set { _stringFormat = value; CheckInitialize(); } } Binding _binding; public Binding Binding { get { return _binding; } set { _binding = value; CheckInitialize(); } } void CheckInitialize() { if (StringFormat == null || Binding == null) { return; }// need both Setters.Add(CreateSetter(Binding, StringFormat)); var trigger = new Trigger { Property = UIElement.IsKeyboardFocusWithinProperty, Value = true, }; trigger.Setters.Add(CreateSetter(Binding)); Triggers.Add(trigger); } /// <summary>Creates the common <see cref="Setter"/>.</summary> static Setter CreateSetter(Binding binding, string stringFormat = null) { // must create a copy, because same binding ref but diff StringFormats var bindingCopy = new Binding { // these could be copies as well UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged, ValidatesOnDataErrors = true, Mode = BindingMode.TwoWay, Path = binding.Path, AsyncState = binding.AsyncState, BindingGroupName = binding.BindingGroupName, BindsDirectlyToSource = binding.BindsDirectlyToSource, Converter = binding.Converter, ConverterCulture = binding.ConverterCulture, ConverterParameter = binding.ConverterParameter, ElementName = binding.ElementName, FallbackValue = binding.FallbackValue, IsAsync = binding.IsAsync, NotifyOnSourceUpdated = binding.NotifyOnSourceUpdated, NotifyOnTargetUpdated = binding.NotifyOnTargetUpdated, NotifyOnValidationError = binding.NotifyOnValidationError, //StringFormat = set below... TargetNullValue = binding.TargetNullValue, UpdateSourceExceptionFilter = binding.UpdateSourceExceptionFilter, ValidatesOnExceptions = binding.ValidatesOnExceptions, XPath = binding.XPath, //ValidationRules = binding.ValidationRules }; // mutex ElementName, so modify if needed // Source = binding.Source, // RelativeSource = binding.RelativeSource, if (stringFormat != null) { bindingCopy.StringFormat = stringFormat; } return new Setter(TextBox.TextProperty, bindingCopy); } } 

Please note that my test was

  • shared mainwindow
  • impl INotifyPropertyChanged
  • SomeValue Property
  • DataContext = this
  • x: Name = This
+2
source share

My attempt to resolve this ended with a special control plus multiconnection, both of which were proposed above.

This allowed me to use markup as follows:

<CustomTextBox Value = "{Binding Value}} Format =" N2 "/">

I tried to publish my code, but I always get the error message "code that is not formatted correctly as code."

+2
source share

I am wondering, maybe you can have an attached property for editing to save the formatted value (only tied to the actual editing value when applying Stringformat), and then in your inaccurate trigger you can set the editing value to this property.

This will lead to a circular binding, although when editing has no focus, I don’t know how WPF reacts in such situations.

0
source share

Unfortunately, this (as far as I know) is impossible. One possible workaround would be to programmatically create a style on the fly that can be encapsulated in MarkupExtension , which takes a path as a constructor parameter.

0
source share

All Articles