为了说明我的项目,我创建了一个WPF项目。
免责声明:我仅使用Caliburn.Micro来使用PropertyChangedBase
和BindableCollection
。此项目中的其他所有内容都是样板WPF内容。
是的,所以,我有一个班级DataItem
。它只有两个属性:
int
Qty
和Sum
的计算属性,其中
是Qty
的两倍。那就是它。为清楚起见,这里是代码:
public class DataLine : PropertyChangedBase
{
private int qty;
public int Qty
{
get
{
return qty;
}
set
{
if (value == qty)
{
return;
}
qty = value;
NotifyOfPropertyChange();
NotifyOfPropertyChange(() => Sum);
}
}
public int Sum => qty * 2;
public DataLine(int a)
{
Qty = a;
}
}
现在,ViewModel。它已经
了BindableCollection
的{{1}}(Caliburn的ObservableCollection
风味)DataLine
,int
,它将Sum
DataLines
的所有NotifyPropertyChanged
加起来, ICommand只为BindableCollection
和int
触发class ViewModel: PropertyChangedBase
{
public ViewModel()
{
Data = new BindableCollection<DataLine>
{
new DataLine(1),
new DataLine(2),
new DataLine(4),
new DataLine(6)
};
RefreshCommand = new RefreshCommand(this);
}
private BindableCollection<DataLine> _data;
public BindableCollection<DataLine> Data
{
get
{
return _data;
}
set
{
if (value == _data)
{
return;
}
_data = value;
NotifyOfPropertyChange();
NotifyOfPropertyChange(() => Amount);
}
}
public ICommand RefreshCommand { get; private set; }
public void RefreshAction()
{
NotifyOfPropertyChange(() => Data);
NotifyOfPropertyChange(() => Amount);
}
public int? Amount => Data?.Sum(c => c.Sum);
}
。
以下是代码:
View
现在,对于DataGrid
:
这很简单。
BindableCollection
,绑定到Button
。ICommand
,绑定到, bound to
。View
Amount`。这是<DockPanel>
<TextBox DockPanel.Dock="Bottom" Text="{Binding Amount, TargetNullValue='', Mode=OneWay}"/>
<Button DockPanel.Dock="Bottom" Command="{Binding RefreshCommand}" Content="Refresh"/>
<DataGrid ItemsSource="{Binding Data, UpdateSourceTrigger=PropertyChanged}" AutoGenerateColumns="True"/>
</DockPanel>
:
DataGrid
当我运行它时,我得到这样的东西:
现在是棘手的部分 - 让我只编辑其中一行。
为了清楚起见,我在编辑Sum
后添加了一个箭头来显示光标所在的位置。检查第一行Amount
的更新方式,但屏幕底部的Refresh
保持不变。
现在,当我点击Amount
时,会发生这种情况:
DataGrid
现已正确更新。
所有这些最终都让我想到了问题:DataGrid
有什么问题?为什么Open()
在编辑行时不会触发其setter?我怎样才能确保它被触发?
答案 0 :(得分:1)
我发现Datagrids并且有时会更新meta / aggregate数据。 目前我同意Clemens的观点,我不确定您是否可以轻松更改BindableCollection以满足您的需求。
但是,在DataLine
和ViewModel
之间建立紧密联系的快速解决方案是使用可通过的操作。你总是可以看到一些抽象或泛型。但是我创建了一个简单的代码编辑来显示我的意思。
基本上,您创建了一种机制,使ViewModel
可以将Action传递给Object。如果我实现这个,我可能会实现某种形式的Interface或Generic,这使我无法为每个Model添加Action方法。或者至少从具有Notify Action的类继承。为了清晰和易于阅读,生病只需做一个简单的编辑。
在您的DataLine中添加:
//NotifyOfPropertyChange();
//NotifyOfPropertyChange(() => Sum);
NotifyFromParent?.Invoke();
到您的Qty
制定者,并且:
public DataLine(int a, System.Action action = null)
{
Qty = a;
NotifyFromParent = action;
}
public System.Action NotifyFromParent;
然后在你的ViewModel中你可以去:
Data = new BindableCollection<DataLine>
{
new DataLine(1, () => RefreshAction()),
new DataLine(2, () => RefreshAction()),
new DataLine(4, () => RefreshAction()),
new DataLine(6, () => RefreshAction())
};
就像我说的那样,你可以让这个更加漂亮。据我所知,您需要创建一种机制来在数据网格中编辑单元格时更新聚合或外部数据,并且您希望更新立即执行所述编辑。