WPF UI自动填充文本框

时间:2015-11-26 01:07:43

标签: c# .net wpf xaml

我正在.Net 4.5中编写WPF MVVM应用程序,需要以下问题的帮助: 我有带有数值的文本框,例如110000,当两个11都被删除时,UI自动填充框的编号为0.而不是我希望它留在0000。 图片有助于说明问题。

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

它接缝将文本框绑定为double属性,当它变为0000时,它会自动将其更正为0。

4 个答案:

答案 0 :(得分:0)

显示一些代码。

根据您的说法,我建议您处理TextChanged事件并检查更改后的值。如果为0,则将0000放在文本框中。

答案 1 :(得分:0)

你能试试吗?

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

这是一个想法......

在RatedVoltage属性和CutomTextBox之间添加一个间接级别。

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

这是一个代码示例,它将执行我刚刚概述的内容。

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