Caliburn Micro MVVM INotifyPropertyChange
Caliburn Micro MVVM INotifyPropertyChange
所以我正在使用 Cliburn Micro,我有一个 Bindablecollection,我们称它为用户。
public BindableCollection<UserModel> Users
{
get { return _users; }
set
{
_users = value;
NotifyOfPropertyChange(() => Users);
}
}
现在它链接到一个包含两列 FirstName 和 LastName 的数据网格
在另一个面板中,数据网格的选定项目被设置
<DataGrid x:Name="AllUsers" SelectionMode="Single" Margin="5"
SelectionUnit="FullRow" AutoGenerateColumns="False"
CanUserAddRows="False" CanUserDeleteRows="False"
CanUserReorderColumns="False"
IsReadOnly="True" Style="{DynamicResource DataGridUsers}"
SelectedItem="{Binding Path=SelectedUser, Mode=TwoWay}"
cal:Message.Attach="[Event MouseDoubleClick] = [Action DoubleClickUser()]">
<DataGrid.Columns>
<DataGridTextColumn Header="First Name" Binding="{Binding Path=FirstName}" Width="*"/>
<DataGridTextColumn Header="Last Name" Binding="{Binding Path=LastName}" Width="*"/>
</DataGrid.Columns>
</DataGrid>
然后我创建了一个 TextBoxFirstName 并且我只在它不为 null 时设置该值
<DockPanel>
<Label x:Name="LabelFirstName" Width="80" HorizontalContentAlignment="Left" VerticalAlignment="Center" Foreground="#FFAD231F" FontFamily="Lucida Sans Unicode" FontSize="12" >First Name</Label>
<TextBox x:Name="TextBoxFirstName" Margin="0,0,5,0" Text="{Binding
UpdateSourceTrigger=PropertyChanged, Path=TextBoxFirstName,
ValidatesOnDataErrors=true, NotifyOnValidationError=true}"
HorizontalAlignment="Stretch" Height="23" TextAlignment="Center" TextWrapping="NoWrap" VerticalAlignment="Top" Style="{StaticResource RoundedTextBox}" FontFamily="Lucida Sans Unicode"/>
</DockPanel>
我对文本框的错误验证是,
public string this[string columnName]
{
get
{
string result = null;
if (columnName == "TextBoxFirstName")
{
if (string.IsNullOrEmpty(TextBoxFirstName))
{
result = "Please enter a First Name";
}
else
{
SelectedUser.FirstName = TextBoxFirstName;
NotifyOfPropertyChange(() => SelectedUser);
}
}
return result;
}
}
现在我知道 SelectedUser.FirstName 已更新,就好像我将另一个文本框数据绑定设置为 SelectedUser.FirstName 它会按预期更新,但是当我更改它时它不会更新数据网格?
但是如果我更新第二个文本框(具有绑定 SelectedUser.FirstName 的文本框)中的值,它会更新数据网格,
有什么想法吗??
基本上我只想在文本框中的值通过验证时更新数据网格。
假设我不想编辑数据网格本身的值。
快把我逼疯了我知道这一定是它通知的方式,但我无法让它工作,我对 c# 和 MVVM 和 WPF 还很陌生,如果有任何帮助,我们将不胜感激。谢谢
您需要对 FirstName 而不是 SelectedUser 进行 NotifyOfPropertyChange。最好在 FirstName setter.
中执行此操作
所以,我实现 IDataError 的方式是错误的,您不需要在 else 语句中设置值。
The way i should have implemented it.
应该在我的模型而不是视图模型中使用它。
我的模型也是这样的,
namespace App.Models
{
public class ConfigModel : INotifyPropertyChanged
{
private bool _showConfig;
public event PropertyChangedEventHandler PropertyChanged;
public bool ShowConfig
{
get { return this._showConfig; }
set
{
this._showConfig = value;
this.OnPropertyChanged("ShowConfig");
}
}
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
感谢 Wes 和 Mark 的帮助,为我指明了正确的方向。
所以我正在使用 Cliburn Micro,我有一个 Bindablecollection,我们称它为用户。
public BindableCollection<UserModel> Users
{
get { return _users; }
set
{
_users = value;
NotifyOfPropertyChange(() => Users);
}
}
现在它链接到一个包含两列 FirstName 和 LastName 的数据网格 在另一个面板中,数据网格的选定项目被设置
<DataGrid x:Name="AllUsers" SelectionMode="Single" Margin="5"
SelectionUnit="FullRow" AutoGenerateColumns="False"
CanUserAddRows="False" CanUserDeleteRows="False"
CanUserReorderColumns="False"
IsReadOnly="True" Style="{DynamicResource DataGridUsers}"
SelectedItem="{Binding Path=SelectedUser, Mode=TwoWay}"
cal:Message.Attach="[Event MouseDoubleClick] = [Action DoubleClickUser()]">
<DataGrid.Columns>
<DataGridTextColumn Header="First Name" Binding="{Binding Path=FirstName}" Width="*"/>
<DataGridTextColumn Header="Last Name" Binding="{Binding Path=LastName}" Width="*"/>
</DataGrid.Columns>
</DataGrid>
然后我创建了一个 TextBoxFirstName 并且我只在它不为 null 时设置该值
<DockPanel>
<Label x:Name="LabelFirstName" Width="80" HorizontalContentAlignment="Left" VerticalAlignment="Center" Foreground="#FFAD231F" FontFamily="Lucida Sans Unicode" FontSize="12" >First Name</Label>
<TextBox x:Name="TextBoxFirstName" Margin="0,0,5,0" Text="{Binding
UpdateSourceTrigger=PropertyChanged, Path=TextBoxFirstName,
ValidatesOnDataErrors=true, NotifyOnValidationError=true}"
HorizontalAlignment="Stretch" Height="23" TextAlignment="Center" TextWrapping="NoWrap" VerticalAlignment="Top" Style="{StaticResource RoundedTextBox}" FontFamily="Lucida Sans Unicode"/>
</DockPanel>
我对文本框的错误验证是,
public string this[string columnName]
{
get
{
string result = null;
if (columnName == "TextBoxFirstName")
{
if (string.IsNullOrEmpty(TextBoxFirstName))
{
result = "Please enter a First Name";
}
else
{
SelectedUser.FirstName = TextBoxFirstName;
NotifyOfPropertyChange(() => SelectedUser);
}
}
return result;
}
}
现在我知道 SelectedUser.FirstName 已更新,就好像我将另一个文本框数据绑定设置为 SelectedUser.FirstName 它会按预期更新,但是当我更改它时它不会更新数据网格? 但是如果我更新第二个文本框(具有绑定 SelectedUser.FirstName 的文本框)中的值,它会更新数据网格,
有什么想法吗?? 基本上我只想在文本框中的值通过验证时更新数据网格。 假设我不想编辑数据网格本身的值。
快把我逼疯了我知道这一定是它通知的方式,但我无法让它工作,我对 c# 和 MVVM 和 WPF 还很陌生,如果有任何帮助,我们将不胜感激。谢谢
您需要对 FirstName 而不是 SelectedUser 进行 NotifyOfPropertyChange。最好在 FirstName setter.
中执行此操作所以,我实现 IDataError 的方式是错误的,您不需要在 else 语句中设置值。 The way i should have implemented it.
应该在我的模型而不是视图模型中使用它。
我的模型也是这样的,
namespace App.Models
{
public class ConfigModel : INotifyPropertyChanged
{
private bool _showConfig;
public event PropertyChangedEventHandler PropertyChanged;
public bool ShowConfig
{
get { return this._showConfig; }
set
{
this._showConfig = value;
this.OnPropertyChanged("ShowConfig");
}
}
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
感谢 Wes 和 Mark 的帮助,为我指明了正确的方向。