我在WPF DataGrid中有两个按钮,它们的样式将在运行时更改。
当我点击编辑按钮时,DataGridRow必须进入编辑模式&两个按钮的样式应为:
当我点击保存或取消两个按钮应该有样式:
当我点击删除按钮时,不会发生样式更改。
我曾尝试过两次完成此任务:
实际和示例项目
以下是我实际应用的代码:
(下面仅显示代码的一些必要部分,完整代码请从上面的链接下载解决方案)
PartyView.xaml
<!--Some Code-->
<DataGridTemplateColumn Header="Edit" Width="50" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Button x:Name="btnEdit" Style="{StaticResource ResourceKey=EditButton}" Height="35" Width="35"
Visibility="{Binding DataContext.IsInEdit, ElementName=uc,
Converter={StaticResource boolToVisibilityInverseConverter}}"
Click="EditButton_Click"
Command="{Binding DataContext.EditCommand, ElementName=uc}"/>
<Button x:Name="btnSave" Grid.Row="1" Style="{StaticResource ResourceKey=SaveButton}" Height="35" Width="35"
Visibility="{Binding DataContext.IsInEdit, ElementName=uc,
Converter={StaticResource boolToVisibilityConverter}}"
Click="SaveButton_Click"
Command="{Binding DataContext.SaveCommand, ElementName=uc}"/>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Delete" Width="70" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Button x:Name="btnDelete" Style="{StaticResource ResourceKey=DeleteButton}" Height="35" Width="35"
Visibility="{Binding DataContext.IsInEdit, ElementName=uc,
Converter={StaticResource boolToVisibilityInverseConverter}}"
Command="{Binding DataContext.DeleteCommand, ElementName=uc}"/>
<Button x:Name="btnCancel" Grid.Row="1" Style="{StaticResource ResourceKey=CancelButton}" Height="35" Width="35"
Visibility="{Binding DataContext.IsInEdit, ElementName=uc,
Converter={StaticResource boolToVisibilityConverter}}"
Command="{Binding DataContext.CancelCommand, ElementName=uc}"
Click="CancelButton_Click"/>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<!--Some Code-->
在CodeBehind中:
//Some Code
private void EditButton_Click(object sender, RoutedEventArgs e)
{
int rowIndex = 0;
DependencyObject dep = (DependencyObject)e.OriginalSource;
while (dep != null && !(dep is DataGridCell))
{
dep = VisualTreeHelper.GetParent(dep);
}
if (dep == null)
return;
DataGridRow row = null;
if (dep is DataGridCell)
{
while (dep != null && !(dep is DataGridRow))
{
dep = VisualTreeHelper.GetParent(dep);
}
row = (DataGridRow)dep;
rowIndex = FindRowIndex(row);
}
while (dep != null && !(dep is DataGrid))
{
dep = VisualTreeHelper.GetParent(dep);
}
if (dep == null)
return;
DataGrid dg = (DataGrid)dep;
dg.CurrentCell = new DataGridCellInfo(dg.Items[rowIndex], dg.Columns[0]);
dg.BeginEdit();
for (int column = 0; column <= dg.Columns.Count - 1; column++)
{
if (!(GetDataGridCell(new DataGridCellInfo(dg.Items[rowIndex], dg.Columns[column])).IsReadOnly && GetDataGridCell(new DataGridCellInfo(dg.Items[rowIndex], dg.Columns[column])).IsEditing))
{
GetDataGridCell(new DataGridCellInfo(dg.Items[rowIndex], dg.Columns[column])).IsEditing = true;
}
}
var rows = GetDataGridRows(dg);
foreach (DataGridRow r in rows)
{
if (!(r.IsEditing))
{
r.IsEnabled = false;
}
}
}
private void SaveButton_Click(object sender, RoutedEventArgs e)
{
int rowIndex = 0;
DependencyObject dep = (DependencyObject)e.OriginalSource;
while (dep != null && !(dep is DataGridCell))
{
dep = VisualTreeHelper.GetParent(dep);
}
if (dep == null)
return;
DataGridRow row = null;
if (dep is DataGridCell)
{
while (dep != null && !(dep is DataGridRow))
{
dep = VisualTreeHelper.GetParent(dep);
}
row = (DataGridRow)dep;
rowIndex = FindRowIndex(row);
}
while (dep != null && !(dep is DataGrid))
{
dep = VisualTreeHelper.GetParent(dep);
}
if (dep == null)
return;
DataGrid dg = (DataGrid)dep;
dg.CommitEdit(DataGridEditingUnit.Row, true);
for (int column = 0; column <= dg.Columns.Count - 1; column++)
{
if (!(GetDataGridCell(new DataGridCellInfo(dg.Items[rowIndex], dg.Columns[column])).IsReadOnly))
{
GetDataGridCell(new DataGridCellInfo(dg.Items[rowIndex], dg.Columns[column])).IsEditing = false;
}
}
var rows = GetDataGridRows(dg);
foreach (DataGridRow r in rows)
{
r.IsEnabled = true;
}
}
private void CancelButton_Click(object sender, RoutedEventArgs e)
{
DependencyObject dep = (DependencyObject)e.OriginalSource;
int rowIndex = 0;
DataGridRow row = null;
while (dep != null && !(dep is DataGridRow))
{
dep = VisualTreeHelper.GetParent(dep);
}
row = (DataGridRow)dep;
rowIndex = FindRowIndex(row);
while (dep != null && !(dep is DataGrid))
{
dep = VisualTreeHelper.GetParent(dep);
}
if (dep == null)
return;
DataGrid dg = (DataGrid)dep;
var rows = GetDataGridRows(dg);
dg.CancelEdit(DataGridEditingUnit.Row);
for (int column = 0; column <= dg.Columns.Count - 1; column++)
{
if (!(GetDataGridCell(new DataGridCellInfo(dg.Items[rowIndex], dg.Columns[column])).IsReadOnly))
{
GetDataGridCell(new DataGridCellInfo(dg.Items[rowIndex], dg.Columns[column])).IsEditing = false;
}
}
foreach (DataGridRow r in rows)
{
r.IsEnabled = true;
}
}
public DataGridCell GetDataGridCell(DataGridCellInfo cellInfo)
{
var cellContent = cellInfo.Column.GetCellContent(cellInfo.Item);
if (cellContent != null)
return (DataGridCell)cellContent.Parent;
return null;
}
private int FindRowIndex(DataGridRow row)
{
DataGrid dataGrid = ItemsControl.ItemsControlFromItemContainer(row) as DataGrid;
int index = dataGrid.ItemContainerGenerator.IndexFromContainer(row);
return index;
}
public IEnumerable<DataGridRow> GetDataGridRows(DataGrid grid)
{
var itemsSource = grid.ItemsSource as IEnumerable;
if (null == itemsSource) yield return null;
foreach (var item in itemsSource)
{
var row = grid.ItemContainerGenerator.ContainerFromItem(item) as DataGridRow;
if (null != row) yield return row;
}
}
视图模型:
private bool _isInEdit;
public bool IsInEdit
{
get
{
return _isInEdit;
}
set
{
_isInEdit = value;
OnPropertyChanged(() => IsInEdit);
}
}
private void Edit()
{
IsInEdit = true;
}
private void Save()
{
IsInEdit = false;
SaveToDataBase();
}
private void Cancel()
{
IsInEdit = false;
}
public void SaveToDataBase()
{
_partyClient.UpdateParty(SelectedParty);
}
答案 0 :(得分:1)
我看了你很棒的样本,发现你的通知实现没有成功。所以我改为测试你的ViewModelBase
到BindableBase
https://github.com/PrismLibrary/Prism/blob/master/Source/Prism/Mvvm/BindableBase.cs
现在它按预期工作。
编辑:
您的NotificationObject
不是来自INotifyPropertyChanged
。因此,如果添加继承,它也可以正常工作。