C# WPF MVVM:需要格式的文本框和IsDefault设置为True的按钮
我也发现了类似的问题,除了我的文本框需要在焦点丢失后有一个格式化的值C# WPF MVVM:需要格式的文本框和IsDefault设置为True的按钮,c#,wpf,mvvm,binding,.net-4.0,C#,Wpf,Mvvm,Binding,.net 4.0,我也发现了类似的问题,除了我的文本框需要在焦点丢失后有一个格式化的值 <TextBox Text="{Binding Value}" MaxLength="{Binding MaskLength}"/> <Button Command="{Binding ExecuteCommand}" IsDefault="True"/> 这是我发现的黑客背后最干净的代码。我把它变成了一个附属的财产,但闻起来还是不太对劲 private void _HandleTxtKeyDown(
<TextBox Text="{Binding Value}" MaxLength="{Binding MaskLength}"/>
<Button Command="{Binding ExecuteCommand}" IsDefault="True"/>
这是我发现的黑客背后最干净的代码。我把它变成了一个附属的财产,但闻起来还是不太对劲
private void _HandleTxtKeyDown( object sender, KeyEventArgs e )
{
if( e.Key == Key.Enter )
{
TextBox textBox = (TextBox)sender;
BindingExpression binding = textBox.GetBindingExpression( TextBox.TextProperty );
if( binding != null )
{
binding.UpdateSource();
}
}
}
如果我以正确的方式理解你的意图,事实上没有问题 如果用户按enter键/单击按钮,您只想屏蔽输入,对吗?然后,您已经找到的解决方案(UpdateSourceTrigger=PropertyChanged)将完全按照您的意愿执行。键入时,VM中的属性将更新。如果使用PropertyChanged触发器,则在按enter键/单击按钮之前不会执行该命令 默认的UpdateSourceTrigger为“LostFocus”。当然,如果用鼠标单击按钮,而不是按enter键,也会发生这种情况
希望我能帮助你理解这个机制。你说得不对。如果命令更新文本,则在键入时不会执行该命令,直到您按enter键/单击该按钮 观点:
<Window x:Class="WpfApplication9.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<StackPanel>
<TextBox MaxLength="{Binding Path=MyLength}"
Text="{Binding Path=MyText, UpdateSourceTrigger=PropertyChanged}"/>
<Button Command="{Binding Path=MyCommand}" IsDefault="True">Enter</Button>
</StackPanel>
</Window>
进来
viewmodel,在构造函数中指定为窗口的DataContext:
public class MyViewModel : INotifyPropertyChanged
{
private string _myText = string.Empty;
private int _maxLength = 6;
private ICommand _myCommand;
public MyViewModel()
{
this._myCommand = new MySimpleCommand((obj) => { FormatMyText(); });
}
private void FormatMyText()
{
this.MyText = this.MyText.PadLeft(this.MyLength, '0');
}
public string MyText
{
get { return this._myText; }
set
{
this._myText = value;
PropertyChanged(this, new PropertyChangedEventArgs("MyText"));
}
}
public int MyLength
{
get { return this._maxLength; }
set { }
}
public ICommand MyCommand
{
get { return this._myCommand; }
set { }
}
public event PropertyChangedEventHandler PropertyChanged;
public class MySimpleCommand : ICommand
{
private Action<object> _action;
public MySimpleCommand(Action<object> cmdAction)
{
this._action = cmdAction;
}
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
_action(parameter);
}
}
}
公共类MyViewModel:INotifyPropertyChanged
{
私有字符串_myText=string.Empty;
私有int_maxLength=6;
私人ICommand_myCommand;
公共MyViewModel()
{
this._myCommand=newmysimpleCommand((obj)=>{FormatMyText();});
}
私有void FormatMyText()
{
this.MyText=this.MyText.PadLeft(this.MyLength,'0');
}
公共字符串MyText
{
获取{返回此。\u myText;}
设置
{
这个。_myText=值;
PropertyChanged(这是新的PropertyChangedEventArgs(“MyText”);
}
}
公共国际长度
{
获取{返回这个。_maxLength;}
集合{}
}
公共ICommand MyCommand
{
获取{返回此。_myCommand;}
集合{}
}
公共事件属性更改事件处理程序属性更改;
公共类MySimpleCommand:ICommand
{
私人行动;
public MySimpleCommand(Action cmdAction)
{
这是。_action=cmdAction;
}
公共布尔CanExecute(对象参数)
{
返回true;
}
公共事件处理程序CanExecuteChanged;
public void Execute(对象参数)
{
_作用(参数);
}
}
}
将其设置为PropertyChanged会更新源代码,但格式设置正确。假设我想将值'ab1'格式化为'00AB1'。如果在用户点击“a”时设置为PropertyChanged,则该值将变为“0000A”。现在用户点击“b”,它被忽略,因为已达到最大长度。不,不是。请参阅我的下一个答案,以查看完全工作的代码(已测试):我建议您在MyText属性的setter和FormatMyText()方法中放置断点。希望我能帮助你。是的,那很有效。但是,我的命令没有进行格式化。值属性在更新绑定时进行格式化(OnLostFocus[default]或PropertyChanged)。
public class MyViewModel : INotifyPropertyChanged
{
private string _myText = string.Empty;
private int _maxLength = 6;
private ICommand _myCommand;
public MyViewModel()
{
this._myCommand = new MySimpleCommand((obj) => { FormatMyText(); });
}
private void FormatMyText()
{
this.MyText = this.MyText.PadLeft(this.MyLength, '0');
}
public string MyText
{
get { return this._myText; }
set
{
this._myText = value;
PropertyChanged(this, new PropertyChangedEventArgs("MyText"));
}
}
public int MyLength
{
get { return this._maxLength; }
set { }
}
public ICommand MyCommand
{
get { return this._myCommand; }
set { }
}
public event PropertyChangedEventHandler PropertyChanged;
public class MySimpleCommand : ICommand
{
private Action<object> _action;
public MySimpleCommand(Action<object> cmdAction)
{
this._action = cmdAction;
}
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
_action(parameter);
}
}
}