我正在.Net 4.5中编写WPF MVVM应用程序,需要以下问题的帮助: 我有带有数值的文本框,例如110000,当两个11都被删除时,UI自动填充框的编号为0.而不是我希望它留在0000。 图片有助于说明问题。
修改
<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。
答案 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之间添加一个间接级别。
这是一个代码示例,它将执行我刚刚概述的内容。
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));
}
}
}
结果看起来像这样: