Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# NotifyPropertyChanged,仅当事件绑定到命令时查看更新_C#_Wpf_Mvvm_Inotifypropertychanged_Icommand - Fatal编程技术网

C# NotifyPropertyChanged,仅当事件绑定到命令时查看更新

C# NotifyPropertyChanged,仅当事件绑定到命令时查看更新,c#,wpf,mvvm,inotifypropertychanged,icommand,C#,Wpf,Mvvm,Inotifypropertychanged,Icommand,我对c#和WPF还是相当陌生的,所以也许这是意料之中的,但我觉得很奇怪,我似乎无法摆脱它 我有一个窗口,其中有一个区域可以输入有关事件的信息,还有一个提交按钮以及一些绑定到可观察集合的数据网格。该按钮绑定到我的viewmodel上的一个命令,当输入一个新事件时,我对可观察的集合进行一些更改,并且更新视图上的数据网格 问题在于编辑其中一个数据网格上的单元格时。我已经尝试将celleditended事件绑定到视图模型上的命令,因此我尝试使用代码隐藏事件处理程序以不同的方式进行绑定。我将所需的编辑信息

我对c#和WPF还是相当陌生的,所以也许这是意料之中的,但我觉得很奇怪,我似乎无法摆脱它

我有一个窗口,其中有一个区域可以输入有关事件的信息,还有一个提交按钮以及一些绑定到可观察集合的
数据网格。该按钮绑定到我的viewmodel上的一个命令,当输入一个新事件时,我对可观察的集合进行一些更改
,并且更新视图上的数据网格

问题在于编辑其中一个
数据网格
上的单元格时。我已经尝试将
celleditended
事件绑定到视图模型上的命令,因此我尝试使用代码隐藏事件处理程序以不同的方式进行绑定。我将所需的编辑信息传递给viewmodel,以与上面工作方式完全相同的方式对可观察集合进行更改,并且可以看到
可观察集合中的更改,但视图不会更新。
notifypropertychange
不会启动,
notifycollectionchange
也不会启动

那么为什么
observateCollection
在事件通过命令时似乎只触发属性或集合更改来更新视图呢

完整代码如下:

主窗口视图的XAML代码;这个例子就是我从中得到xcdg:CellEditorBinding位的地方

<Window.Resources>
    <DataTemplate x:Key="DateTextblock">
        <TextBlock Text="{Binding StringFormat={}{0:D}}"/>
    </DataTemplate>

    <xcdg:DataGridCollectionViewSource x:Key="HistoryViewSource" Source="{Binding History, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
        <xcdg:DataGridCollectionViewSource.SortDescriptions>
            <scm:SortDescription PropertyName="Date" Direction="Descending"/>
        </xcdg:DataGridCollectionViewSource.SortDescriptions>
    </xcdg:DataGridCollectionViewSource>

    <ViewModel:MainWindowViewModel x:Key="MainWindowCollections"/>
</Window.Resources>

<Grid>
    <Grid.RowDefinitions>
        <!--Account Balances and Spending goals-->
        <RowDefinition Height="Auto"/>
        <!--History-->
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>

    <Grid Grid.Row="0">
        <Grid.ColumnDefinitions>
            <!--Account Balances-->
            <ColumnDefinition x:Name="AccountsWidth" Width="Auto"/>
            <!--Categorized spending goals-->
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>

        <xcdg:DataGridControl x:Name="AccountsDataGrid"
                              ItemsSource="{Binding Accounts, UpdateSourceTrigger=PropertyChanged}"
                              AutoCreateColumns="False"
                              SelectionMode="Single" 
                              FontSize="14" 
                              Height="Auto"
                              Width="Auto">

            <xcdg:DataGridControl.Columns>
                <xcdg:Column Title="Account" FieldName="Name">
                    <xcdg:Column.CellEditor>
                        <xcdg:CellEditor>
                            <xcdg:CellEditor.EditTemplate>
                                <DataTemplate>
                                    <TextBox x:Name="AccountText" Text="{Binding Name, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnSourceUpdated=True}" Style="{StaticResource MainTextboxStyle}" MinWidth="100"/>
                                </DataTemplate>
                            </xcdg:CellEditor.EditTemplate>
                        </xcdg:CellEditor>
                    </xcdg:Column.CellEditor>
                </xcdg:Column>

                <xcdg:Column Title="Balance" FieldName="Balance">
                    <xcdg:Column.CellEditor>
                        <xcdg:CellEditor>
                            <xcdg:CellEditor.EditTemplate>
                                <DataTemplate>
                                    <xctk:DecimalUpDown Value="{Binding Balance, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, NotifyOnSourceUpdated=True}" Style="{StaticResource DecimalUpDownStyle}"/>
                                </DataTemplate>
                            </xcdg:CellEditor.EditTemplate>
                        </xcdg:CellEditor>
                    </xcdg:Column.CellEditor>
                </xcdg:Column>
                </xcdg:DataGridControl.Columns>
            </xcdg:DataGridControl>
    </Grid>

    <xcdg:DataGridControl Grid.Row="1" Height="Auto" x:Name="HistoryDataGrid" ItemsSource="{Binding Source={StaticResource HistoryViewSource}, UpdateSourceTrigger=PropertyChanged}" AutoCreateColumns="False"  SelectionMode="Single" FontSize="14" xcdg:Cell.EditEnded="HistoryDataGrid_EditEnded"> 
        <!--<i:Interaction.Triggers>
            <i:EventTrigger EventName="SelectionChanged">
                <cmd:EventToCommand PassEventArgsToCommand="True" Command="{Binding TransactionEditCommand}"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>-->

        <xcdg:DataGridControl.Columns>
            <xcdg:Column Title="ID" FieldName="ID" Visible="False"/>
            <xcdg:Column Title="Type" FieldName="Type"/>

            <xcdg:Column Title="Amount" FieldName="Amount">
                <xcdg:Column.CellContentTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding StringFormat={}{0:C}, NotifyOnSourceUpdated=True}"/>
                    </DataTemplate>
                </xcdg:Column.CellContentTemplate>

                <xcdg:Column.CellEditor>
                    <xcdg:CellEditor>
                        <xcdg:CellEditor.EditTemplate>
                            <DataTemplate>
                                <xctk:DecimalUpDown Value="{xcdg:CellEditorBinding NotifyOnSourceUpdated=True}" Style="{StaticResource DecimalUpDownStyle}"/>
                            </DataTemplate>
                        </xcdg:CellEditor.EditTemplate>
                    </xcdg:CellEditor>
                </xcdg:Column.CellEditor>
            </xcdg:Column>
        </xcdg:DataGridControl.Columns>
    </xcdg:DataGridControl>
</Grid>
视图模型代码

public class MainWindowViewModel : GalaSoft.MvvmLight.ObservableObject
{
    public MainWindowViewModel()
    {
        Accounts = DatabaseFunctions.getAccountData();
        History = DatabaseFunctions.getHistoryData();
    }

    private ObservableCollection<AccountsModel> accounts;
    public ObservableCollection<AccountsModel> Accounts
    {
        get { return accounts; }
        set
        {
            accounts = value;
            RaisePropertyChanged("Accounts");
        }
    }

    private ObservableCollection<HistoryModel> history;
    public ObservableCollection<HistoryModel> History
    {
        get { return history; }
        set
        {
            history = value;
            RaisePropertyChanged("History");
            History.CollectionChanged += History_CollectionChanged;
        }
    }

    public ICommand HistoryEditCommand
    {
        get { return new ParamDelegateCommand<RoutedEventArgs>(HistoryCellEdit); }
    }

    public void HistoryCellEdit(RoutedEventArgs e)
    {
        UpdateAccountData("Chequing", 200);
    }

    public void UpdateAccountData(string AccountName, decimal NewBalance)
    {
        var item = Accounts.FirstOrDefault(i => i.Name == AccountName);
        if (item != null)
        {
            item.Balance = NewBalance;
        }
    }

    void Accounts_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.NewItems != null)
            foreach (AccountsModel item in e.NewItems)
                item.PropertyChanged += Accounts_PropertyChanged;
        if (e.OldItems != null)
            foreach (AccountsModel item in e.OldItems)
                item.PropertyChanged -= Accounts_PropertyChanged;
    }

    void History_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.NewItems != null)
            foreach (HistoryModel item in e.NewItems)
                item.PropertyChanged += History_PropertyChanged;
        if (e.OldItems != null)
            foreach (HistoryModel item in e.OldItems)
                item.PropertyChanged -= History_PropertyChanged;
    }

    void Accounts_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {

    }

    void History_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {

    }
}
这个历史模型

public class HistoryModel : ObservableObject
{
    #region Properties
    private Double id;
    public Double ID
    {
        get { return id; }
        set
        {
            id = value;
            RaisePropertyChangedEvent("ID");
        }
    }

    private string type;
    public string Type
    {
        get { return type; }
        set
        {
            type = value;
            RaisePropertyChangedEvent("Type");
        }
    }

    private decimal amount;
    public decimal Amount
    {
        get { return amount; }
        set
        {
            amount = value;
            RaisePropertyChangedEvent("Amount");
        }
    }
}
通知属性已更改

public class ObservableObject : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChangedEvent(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }  
}

将代码添加到model、viewmodel和相关xaml中。这表明您的模型没有实现INotifyPropertyChanged
。如果元素的属性发生更改,
ObseravbleCollection
不会通知视图,除非元素也实现了接口。似乎缺少信息。类别是可观察的集合吗?如果是这样,这些项目本身是否可以观察到?@zaitsman我已经添加了一个分类模型。简而言之,每一个模型的每一个元素都有其本质的变化。UpdateCategoryData位于视图模型中。每当我需要更改Categories observable集合中的值时,就会调用它。至于xaml代码,我甚至不知道哪部分是相关的,但我添加了数据网格位。谢谢您的帮助。@glenebob Categories是可观察的集合,并且模型(据我所知)实现了notifyproperty更改;我已经添加了类别模型的一部分。感谢您的帮助。那么您使用什么绑定从datagrid列到对象属性?将代码添加到model、viewmodel和相关xaml。这表明您的模型没有实现INotifyPropertyChanged。如果元素的属性发生更改,
ObseravbleCollection
不会通知视图,除非元素也实现了接口。似乎缺少信息。类别是可观察的集合吗?如果是这样,这些项目本身是否可以观察到?@zaitsman我已经添加了一个分类模型。简而言之,每一个模型的每一个元素都有其本质的变化。UpdateCategoryData位于视图模型中。每当我需要更改Categories observable集合中的值时,就会调用它。至于xaml代码,我甚至不知道哪部分是相关的,但我添加了数据网格位。谢谢您的帮助。@glenebob Categories是可观察的集合,并且模型(据我所知)实现了notifyproperty更改;我已经添加了类别模型的一部分。感谢您的帮助。那么您使用什么绑定从datagrid列到对象属性?将代码添加到model、viewmodel和相关xaml。这表明您的模型没有实现INotifyPropertyChanged。如果元素的属性发生更改,
ObseravbleCollection
不会通知视图,除非元素也实现了接口。似乎缺少信息。类别是可观察的集合吗?如果是这样,这些项目本身是否可以观察到?@zaitsman我已经添加了一个分类模型。简而言之,每一个模型的每一个元素都有其本质的变化。UpdateCategoryData位于视图模型中。每当我需要更改Categories observable集合中的值时,就会调用它。至于xaml代码,我甚至不知道哪部分是相关的,但我添加了数据网格位。谢谢您的帮助。@glenebob Categories是可观察的集合,并且模型(据我所知)实现了notifyproperty更改;我已经添加了类别模型的一部分。感谢您的帮助那么您使用什么绑定从datagrid列到对象属性呢?
public class HistoryModel : ObservableObject
{
    #region Properties
    private Double id;
    public Double ID
    {
        get { return id; }
        set
        {
            id = value;
            RaisePropertyChangedEvent("ID");
        }
    }

    private string type;
    public string Type
    {
        get { return type; }
        set
        {
            type = value;
            RaisePropertyChangedEvent("Type");
        }
    }

    private decimal amount;
    public decimal Amount
    {
        get { return amount; }
        set
        {
            amount = value;
            RaisePropertyChangedEvent("Amount");
        }
    }
}
public class ObservableObject : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChangedEvent(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }  
}