简体   繁体   中英

Caliburn Micro MVVM INotifyPropertyChange

So I'm using Cliburn Micro and i have a Bindablecollection, lets call it users.

        public BindableCollection<UserModel> Users
    {
        get { return _users; }
        set
        {
            _users = value;
            NotifyOfPropertyChange(() => Users);

        }
    }

Now this is linked to a datagrid with two columns FirstName and LastName In another panel the selected item of the datagrid gets set

                <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>

Then i've created a TextBoxFirstName and i only set the value if its not 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>

My Error Validation over the textbox is,

        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;
        }
    }

Now I know SelectedUser.FirstName is updated as if i set another textbox databinding to SelectedUser.FirstName it updates as expected, but its not updating the Datagrid when i change it? but if i update the value in the secondtextbox (the one with the binding SelectedUser.FirstName) it does update the datagrid,

AnyIdeas?? Basically i only want to update the datagrid if the value in the textbox passes the validation. Assume i don't want to edit the values in the datagrid itself.

Driving me mad I know it must be with the way it notifies but i can't get it to work and im fairly new to c# and MVVM and WPF any help would be much appreciated. thanks

You need to NotifyOfPropertyChange on FirstName instead of SelectedUser. Preferably you should do this in the FirstName setter.

So, The way I was implementing the IDataError was wrong, you don't need to set the the value in an else statement. The way i should have implemented it.

Should have used it in my model not in the viewmodel.

Also My Model looks like this,

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));
        }
    }
}

Thanks for the help from Wes and Mark for pointing me in the right direction.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM