【问题标题】:Caliburn Micro MVVM INotifyPropertyChangeCaliburn Micro MVVM INotifyPropertyChange
【发布时间】:2019-03-12 21:32:07
【问题描述】:

所以我正在使用 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 并且我只设置它不为空的值

                            <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 它会按预期更新,但是当我更改它时它不会更新 Datagrid? 但是如果我更新第二个文本框中的值(具有绑定 SelectedUser.FirstName 的那个),它确实会更新数据网格,

有什么想法吗?? 基本上,如果文本框中的值通过验证,我只想更新数据网格。 假设我不想编辑数据网格本身的值。

让我发疯,我知道它一定是它通知的方式,但我无法让它工作,而且我对 c# 和 MVVM 和 WPF 相当陌生,任何帮助将不胜感激。谢谢

【问题讨论】:

  • UserModel 是否实现了 INotifyPropertyChanged?
  • @Wes 如果您的意思是 selecteduser,那么是的,public UserModel SelectedUser { get { return _selectedUser; } 设置 { _selectedUser = 值; NotifyOfPropertyChange(() => SelectedUser); } }
  • 不,我指的是 UserModel 类而不是 SelectedUser 属性。
  • 对不起,我是新手,在用户模型中设置 inotify 与在我设置它的地方设置它有何不同? MVVM 不是将您的模型数据与与视图交互的代码分开吗?我的意思是它通知我设置为 SelectedUser.FirstName 的另一个文本框,但没有通知绑定到完全相同的 SelectedUser.FirstName 的数据网格?你能举例说明你的意思吗?

标签: c# wpf mvvm caliburn.micro


【解决方案1】:

您需要 NotifyOfPropertyChange 对 FirstName 而不是 SelectedUser。最好在 FirstName 设置器中执行此操作。

【讨论】:

  • 我试过 else { SelectedEmployee.FirstName = TextBoxFirstName; NotifyOfPropertyChange(() => SelectedEmployee.FirstName); } 还是不行?
  • 您需要从用户对象内部提升属性更改。每当更新 LastName 时,尝试提高 LastName 设置器中更改的属性。当然,您的用户对象需要实现 INotifyPropertyChanged。
  • 如果您的数据网格绑定到 UserModel 对象的集合,则 UserModel 必须实现 INotifyPropertyChanged 并且每个可以更改的属性都必须引发 PropertyChanged 事件并传递该属性的名称。否则数据网格文本列将不会收到任何更改的通知。
【解决方案2】:

所以,我实现 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 为我指明正确方向的帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-29
    • 2012-10-24
    • 2012-05-08
    • 1970-01-01
    • 1970-01-01
    • 2021-06-15
    • 2013-10-26
    相关资源
    最近更新 更多