2015-11-26 134 views
0

我在.Net 4.5中编写WPF MVVM应用程序,需要以下问题的帮助: 我有数值为例如110000的文本框,并且当两个11都被删除UI自动填充框包含数字0.相反,我希望它保持0000. 图片来帮助说明问题。WPF UI自动填充文本框

Picture

编辑自定义文本框将其设为默认

static CustomTextBox() 
    { 
    var defaultMetadata = TextBox.TextProperty.GetMetadata(typeof(TextBox)); 

    TextBox.TextProperty.OverrideMetadata(typeof(CustomTextBox), new FrameworkPropertyMetadata(
     string.Empty, FrameworkPropertyMetadataOptions.Journal | FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, 
     defaultMetadata.PropertyChangedCallback, 
     defaultMetadata.CoerceValueCallback, 
     true, 
     System.Windows.Data.UpdateSourceTrigger.PropertyChanged)); 
    } 

物业

 public double RatedVoltage 
    { 
     get { return _RatedVoltage; } 
     set 
     { 
      SetProperty(ref _RatedVoltage, value); 
      if (OnRatedVoltageChanged != null) 
       OnRatedVoltageChanged(); 
     } 
    } 
的PropertyChanged

<src:CustomTextBox VerticalAlignment="Center" 
Text="{Binding TrafoProperties.RatedVoltage, 
Mode=TwoWay, 
ValidatesOnNotifyDataErrors=True, 
NotifyOnValidationError=True}" 

代码

它将文本框绑定为double property,当它更改为0000时,它将自动将其更正为0.

回答

0

这里有一个想法...

添加RatedVoltage财产和CutomTextBox之间的间接级别。

  • 引入一个新的字符串属性与您的控件绑定。例如,将其命名为RatedVoltageText。
  • 将CustomTextBox绑定到RatedVoltageText,Mode = TwoWay。
  • 每当RatedVoltageText的double值发生变化时,请确保RatedVoltage也是变化的。 (将RatedVoltageText与RatedVoltage进行比较是非常重要的,而不是RatedVoltageText与RatedVoltage.ToString())
  • Whenver RatedVoltage更改时,更新RatedVoltageText当且仅当双重表示RatedVoltageText不同于RatedVoltage的新值。

这里是一个代码示例,它将完成我刚刚列出的内容。

MainWindow.xaml:

<Window x:Class="SimpleRibbonWinodw.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:SimpleRibbonWinodw" 
     mc:Ignorable="d" 
     Title="MainWindow" Height="350" Width="525" Background="Gray"> 
    <Window.DataContext> 
     <Binding RelativeSource="{RelativeSource Self}"/> 
    </Window.DataContext> 
    <StackPanel> 
     <Grid> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="1*"/> 
       <ColumnDefinition Width="2*" /> 
      </Grid.ColumnDefinitions> 
      <Label Grid.Column="0" Background="LightGray" Content="SomeValueText (string)"/> 
      <TextBox Text="{Binding SomeValueText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1"/> 
     </Grid> 
     <Grid> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="1*"/> 
       <ColumnDefinition Width="2*" /> 
      </Grid.ColumnDefinitions> 
      <Label Grid.Column="0" Background="LightGray" Content="SomeValue (double)"/> 
      <Label Content="{Binding SomeValue, UpdateSourceTrigger=PropertyChanged ,Mode=OneWay}" Grid.Column="1" Background="Wheat" BorderBrush="Black"/> 
     </Grid> 

    </StackPanel> 
</Window> 

MainWindow.xaml。CS:

using System; 
using System.ComponentModel; 
using System.Diagnostics; 
using System.Windows; 

namespace SimpleRibbonWinodw 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window, INotifyPropertyChanged 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
      PropertyChanged += HandlePropertyChangedEvent; 
     } 

     private void HandlePropertyChangedEvent(object sender, PropertyChangedEventArgs e) 
     { 
      if (string.Equals(e.PropertyName, nameof(SomeValueText), StringComparison.InvariantCultureIgnoreCase)) 
      { 
       double result; 
       if (Double.TryParse(SomeValueText, out result)) 
       { 
        // Do not allow property changed event 
        if (SomeValue != result) 
        { 
         SomeValue = result; 
         Debug.WriteLine($"New value of SomeValue = {SomeValue}"); 
        } 
       } 
      } 

      if (string.Equals(e.PropertyName, nameof(SomeValue), StringComparison.InvariantCultureIgnoreCase)) 
      { 
       double result; 
       if (Double.TryParse(SomeValueText, out result)) 
       { 
        if (result != SomeValue) 
        { 
         SomeValueText = SomeValue.ToString(); 
         Debug.WriteLine($"New value of SomeValueText = {SomeValueText}"); 
        } 
       } 
       else 
       { 
        SomeValueText = SomeValue.ToString(); 
        Debug.WriteLine($"New value of SomeValueText = {SomeValueText}"); 
       } 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 
     public double SomeValue 
     { 
      get { return _someValue; } 
      set 
      { 
       _someValue = value; 
       Debug.WriteLine($"SomeValue Changed: {_someValue}"); 
       RaisePropertyChangedEvent(nameof(SomeValue)); 
      } 
     } 

     private double _someValue; 

     public string SomeValueText 
     { 
      get { return _someValueText; } 
      set 
      { 
       _someValueText = value; 
       RaisePropertyChangedEvent(nameof(SomeValueText)); 
      } 
     } 

     private string _someValueText; 

     protected void RaisePropertyChangedEvent(string propertyName) 
     { 
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

结果会是这个样子:

enter image description here

0

显示一些代码。

从你所说的话,我建议你处理TextChanged事件并检查更改的值。如果其为0,则在文本框中输入0000。

0

你可以试试吗?

<TextBox Text="{Binding Num,StringFormat=0000}"/> 
0

您已经指出了根本原因。由于您正在使用双向模式数据绑定和PropertyChanged作为UpdateSourceTrigger,所以一旦数据绑定被触发,0000将被纠正为有效值(0)。解决方案取决于您的使用案例,您可以使用LostFocus作为UpdateSourceTrigger,并在触发绑定时执行最终验证,并在用户键入时使用TextChanged事件进行补充以便立即进行验证。