2015-11-26 110 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事件進行補充以便立即進行驗證。