最近在用MVVM模式构建WPF程序, 于是利用Prism框架进行开发.
需求:
在此程序设计中需要用到一个表格来自定义添加命令和坐标等,需要用到增加和删除的动作.第一列为序号列,且在增删查改时序号会自动根据当前行数更新
解决过程:
这个问题搞了挺久的,试了各种办法,在打断点的时候发现,DataGrid删除后时可以触发CollectionChanged事件的,于是就将该事件的触发关联一个自动排序方法放在ViewModel的构造方法中.翻来覆去的删除增加之后序号仍然不更新,按理说ObservableCollection时可以自动通知到UI的. 接着继续打断点看到, 在增删之后, 后台的集合中的序号是更新并正确的,但是前台看不到. 所以问题一定是序号更新之后没有通知到前端,也就是绑定时没有触发propertychanged,
于是在DataGrid绑定的数据源类中将序号属性Index进行更改
代码如下,希望可以帮助到你!
代码:
1.XAML
<DataGrid x:Name="MotionDataGrid"
AutoGenerateColumns="False"
SelectedItem="{Binding SelectedProcessItem}"
ItemsSource="{Binding MotionProcess}"
CanUserSortColumns="False"
>
<DataGrid.Columns>
<DataGridTextColumn Header="序号"
Width="70"
Binding="{Binding Index}">
</DataGridTextColumn>
<!--<DataGridComboBoxColumn Header="命令"
Width="100"
SelectedItemBinding="{Binding CommandType}"
DisplayMemberPath="ToString"
ItemsSource="{Binding CommandTypeList}" />-->
<DataGridTemplateColumn Header="命令"
Width="100">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox x:Name="cellComboBox0"
ItemsSource="{x:Static VM:MotionProcessViewModel.CommandTypeList}"
SelectedItem="{Binding StepCommandType, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="X轴"
Width="100"
Binding="{Binding XCoordinate}" />
<DataGridTextColumn Header="Y轴"
Width="100"
Binding="{Binding YCoordinate}" />
<DataGridTextColumn Header="Z轴"
Width="100"
2.ViewModel
集合参数:
public class MotionStep:BindableBase
{
// public int Index { get; set; }
private int _Index;
public int Index
{
get { return _Index; }
set { SetProperty(ref _Index, value); }
}//主要是这里没有属性更改通知
public CommandType StepCommandType { get; set; }
public float XCoordinate { get; set; }
public float YCoordinate { get; set; }
public float ZCoordinate { get; set; }
public float ACoordinate { get; set; }
public float Speed { get; set; }// 预设速度值
}
构造方法:
//数据源 动态集合声明
public ObservableCollection<MotionStep> _motionProcess = new ObservableCollection<MotionStep>();
public ObservableCollection<MotionStep> MotionProcess
{
get { return _motionProcess; }
set { SetProperty(ref _motionProcess, value); }
}
#region 构造方法
public MotionProcessViewModel(IEventAggregator ea)
{
InitialParam();
_ea = ea;
//_motionProcess = new ObservableCollection<MotionStep>();
//订阅事件
_ea.GetEvent<SentMotionEvent>().Subscribe((Zmotion motion) => this._motion = motion);//获取控制卡对象
_ea.GetEvent<SentShellbtnToOther>().Subscribe(ExecuteShellbtnEvent);//判定主窗口传入按钮
//集合更改之后调用排序方法
MotionProcess.CollectionChanged += (s,e) => { AutoUpdateRowNum(); };
}
#endregion
排序方法:
//重新排序
private void AutoUpdateRowNum()
{
for (int i = 0; i < MotionProcess.Count; i++)
{
MotionProcess[i].Index = i + 1;
}
}