2015-11-26 6 views
0

Я пишу приложение WPF MVVM в .Net 4.5 и нуждаюсь в помощи со следующей проблемой: У меня есть текстовое поле с числовым значением, например 110000, и когда оба из них удалены. 0. Вместо этого я хотел бы, чтобы он оставался с 0000. Изображение, чтобы помочь проиллюстрировать проблему.Текстовое поле автозаполнения WPF UI

Picture

Редактировать

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

код для пользовательского текстового поля это набор PropertyChanged по умолчанию

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(); 
     } 
    } 

Это швы, что текстовое поле привязано к двойному свойству, и когда оно изменяется на 0000, его авто исправляет его до 0.

ответ

0

Вот идея ...

Добавить уровень косвенности между RatedVoltage собственности и CutomTextBox.

  • Внесите новое свойство строки, чтобы связать его с вашим контролем. Например, назовите его RatedVoltageText.
  • Bind CustomTextBox to RatedVoltageText, Mode = TwoWay.
  • При изменении двойного значения RatedVoltageText убедитесь, что значение RatingVoltage также изменено. (Важно, чтобы вы сравнивали (double) RatedVoltageText с номинальным напряжением, а не с номинальным напряжением с номинальным напряжением. ToString())
  • Когда переменные изменения напряжения обновляются, обновите 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 для немедленной проверки при вводе пользователем.

Смежные вопросы