我仍然是c#和WPF的新手,所以也许这是预期的但我发现它很奇怪,我似乎无法解决它。
我有一个窗口,其中包含一个区域,用于输入有关事件和提交按钮的信息以及一些绑定到datagrids
的{{1}}。该按钮绑定到我的viewmodel上的命令,当输入新事件时,我对observable collections
进行了一些更改,并更新了视图上的observable collections
。
问题是编辑datagrids
之一上的单元格时。我已经尝试将datagrids
事件绑定到我的视图模型without much success上的命令,所以我通过使用事件处理程序后面的代码以不同的方式尝试它。我将所需的编辑信息传递给viewmodel,以与上面工作方式完全相同的方式对可观察集合进行更改,并且可以看到celleditended
中的更改,但视图不会更新。 observable collection
不会触发,notifypropertychange
也不触发。
那么为什么notifycollectionchange
似乎只触发属性或集合更改以在事件通过命令时更新视图?
完整代码如下:
主窗口视图的XAML代码;示例here是我从中获取xcdg:CellEditorBinding位的地方。
observablecollection
文件后面的查看代码
<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 partial class MainWindow : Window
{
MainWindowViewModel mainwindowviewmodel = new MainWindowViewModel();
public MainWindow()
{
InitializeComponent();
DataContext = new MainWindowViewModel();
}
public void HistoryDataGrid_EditEnded(object sender, RoutedEventArgs e)
{
mainwindowviewmodel.HistoryCellEdit(e);
}
}
帐户模型
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 AccountsModel : ObservableObject
{
private Double id;
public Double ID
{
get { return id; }
set
{
id = value;
RaisePropertyChangedEvent("ID");
}
}
private string name;
public string Name
{
get { return name; }
set
{
name = value;
RaisePropertyChangedEvent("Name");
}
}
private decimal balance;
public decimal Balance
{
get { return balance; }
set
{
balance = value;
RaisePropertyChangedEvent("Balance");
}
}
}
通知属性已更改
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");
}
}
}