警告 - 对于WPF,我是一个新手。所以我要做的是有一个文本框绑定到我的ViewModel中的字符串属性。当用户清除文本框时,我希望它自动返回到用户最初的状态(打开窗口时)。基本上我阻止用户清除文本框。
目前,我的WPF绑定为TwoWay,而且我确实将UpdateSourceTrigger设置为PropertyChanged。我想我想保留UpdateSourceTrigger,因为我喜欢我的ViewModel中的属性,以便在用户进行一点改动时获得更新。这样我可以在用户执行某些操作时执行其他UI操作(例如,更新我的“保存”按钮,因为用户更改了某些内容)。
我的ViewModel中的属性目前看起来像这样,我尝试使用原始值:
public string SourceName
{
get { return this.sourceName; }
set
{
if (!this.sourceName.Equals(value, StringComparison.OrdinalIgnoreCase))
{
if (!string.IsNullOrWhiteSpace(value))
this.sourceName = value;
else
this.sourceName = this.configuredSource.Name;
RaisePropertyChanged("SourceName");
}
}
}
我遇到的问题是我认为View忽略了我的'RaisePropertyChanged',因为我设置了UpdateSourceTrigger。如果我取出触发器,那么这是有效的,但我必须失去对控件的关注才能进行UI更新。因此,如果可以,我想保留触发器的原因。
如果用户清除文本框,任何人都有一种很好的方法可以恢复原始值吗?
答案 0 :(得分:0)
问题不在于UpdateSourceTrigger
,而是就WPF而言,它传递给你的财产的价值是它将承担的价值。它会忽略您为了避免递归循环而引发的属性更改事件。
您需要在单独的消息中引发事件,如下所示:
public string SourceName
{
get { return this.sourceName; }
set
{
if (!this.sourceName.Equals(value, StringComparison.OrdinalIgnoreCase))
{
if (!string.IsNullOrWhiteSpace(value))
{
this.sourceName = value;
RaisePropertyChanged("SourceName");
}
else
{
this.sourceName = this.configuredSource.Name;
this.dispatcherService.BeginInvoke(() => this.RaisePropertyChanged("SourceName"));
}
}
}
}
这是一种伪代码,因为没有标准方法可以从您的VM访问Dispatcher
(除非您的MVVM框架提供了一个)。我通常将它包装在一个具有良好接口的服务中,用于同步和异步调用,如上所示。
无论如何,重点是WPF这次会得到这个事件,因为它是在一个单独的消息中。因此,用户界面将反映您的更改。
答案 1 :(得分:0)
我得到了它的工作。解决方案是让我的财产成为'笨蛋'并允许它被设置为空。
public string SourceName
{
get { return this.sourceName; }
set
{
if (!this.sourceName.Equals(value, StringComparison.OrdinalIgnoreCase))
{
this.sourceName = value;
RaisePropertyChanged("SourceName");
}
}
}
然后我会有一个RelayCommand(MVVM Light),当文本框上的焦点丢失时会被触发。
public RelayCommand SourceNameLostFocusCommand
{
get
{
return new RelayCommand(() =>
{
if (string.IsNullOrWhiteSpace(this.SourceName))
this.SourceName = this.configuredSource.Title;
});
}
}
以下是我的xaml片段,让RelayCommand在失去焦点时触发:
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
<TextBox Text="{Binding Path=SourceName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="LostFocus">
<cmd:EventToCommand Command="{Binding SourceNameLostFocusCommand, Mode=OneWay}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>