我有一个TextBox,其Value绑定到ViewModel属性:
<TextBox Name="txtRunAfter" Grid.Column="4" Text="{Binding Mode=TwoWay, Path=RunAfter}" Style="{StaticResource TestStepTextBox}"/>
set和get工作正常,直到我设置Value时添加一些验证:
private int _runAfter = 0;
public string RunAfter
{
get
{
return _runAfter.ToString();
}
set
{
int val = int.Parse(value);
if (_runAfter != val)
{
if (val < _order)
_runAfter = val;
else
{
_runAfter = 0;
OnPropertyChanged("RunAfter");
}
}
}
}
虽然已达到OnPropertyChanged(我已经相同),但视图不会更改。 我怎样才能做到这一点?
谢谢, JoséTavares
答案 0 :(得分:5)
问题是,在Binding
更新您的媒体资源时,您正在更新Binding
的来源。 WPF在响应PropertyChanged
更新时引发Binding
事件时,实际上不会检查您的属性值。您可以使用Dispatcher
来延迟事件在该分支中的传播来解决此问题:
set
{
int val = int.Parse(value);
if (_runAfter != val)
{
if (val < _order)
{
_runAfter = val;
OnPropertyChanged("RunAfter");
}
else
{
_runAfter = 0;
Dispatcher.CurrentDispatcher.BeginInvoke(
new Action<String>(OnPropertyChanged),
DispatcherPriority.DataBind, "RunAfter");
}
}
}
<强>更新强>
我注意到的另一件事是Binding
上的TextBox
使用的是默认UpdateSourceTrigger
,当TextBox
失去焦点时会发生这种情况。在此TextBox
失去焦点之后,您才会看到文本更改回0。如果您将其更改为PropertyChanged
,您会立即看到这种情况。否则,在TextBox
失去焦点之前,您的财产将无法设置:
<TextBox Name="txtRunAfter" Grid.Column="4" Text="{Binding RunAfter, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource TestStepTextBox}"/>
答案 1 :(得分:3)
我在这里注意到的一些事情。
除非你有令人信服的理由将RunAfter属性公开为字符串,否则没有理由不能将它作为int。这样可以节省你在setter中的强制转换(以及如果用户在字段中输入非整数的东西,可能会出现潜在的InvalidCastException)。
其次,OnPropertyChanged()调用应该发生在内部if语句之外,如下所示:
if(_runAfter != val)
{
if(val < _order)
_runAfter = val;
else
_runAfter = 0;
OnPropertyChanged("RunAfter");
}
由于在条件的两个路径中都更新了_runAfter本地,因此无论采用哪个分支,都必须调用OnPropertyChanged()。我希望这有助于指明你正确的方向!
答案 2 :(得分:1)
我有同样的情况。我写了以下内容并且有效。
<TextBox Grid.Column="3" Grid.Row="0" HorizontalAlignment="Left" VerticalAlignment="Center" Width="100" Text="{Binding Path=FirstName}"></TextBox>
并且
public string FirstName
{
get { return _client.FirstName; }
set
{
if (value == _client.FirstName)
return;
else
_client.FirstName = value;
OnPropertyChanged("FirstName");
}
}