Wpf设置datagridrow MVVM中所有单元格的编辑模式

13z8s7eq  于 2023-01-21  发布在  其他
关注(0)|答案(1)|浏览(282)

在WPF应用程序中使用MVVM模式时,我想设置行中记录的"Editing State"。
每次用户通过点击"编辑"按钮开始编辑记录时,该行应切换到"编辑"模式。
完成后,他可以通过单击同一按钮或其他按钮来保存该行中的所有更改
如何在单击"编辑"按钮时为选定行中的所有单元格设置编辑模式(IsReadOnly = true/false)?
任何帮助都是感激的!
这是我的当前代码:
XAML语言

<Window x:Class="TotalRows.TotalRowsWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:TotalRows" 
    mc:Ignorable="d"
    x:Name="xMainWindow"
    Title="RowsTotalWindow" Height="450" Width="800">
    
    <Window.DataContext>
        <local:ExampleData/>
    </Window.DataContext>
    <Grid>
        <StackPanel >
            <DataGrid x:Name="myGrid" IsReadOnly="True" CanUserAddRows="False" SelectionMode="Single" CanUserDeleteRows="False" 
              ItemsSource="{Binding ItemsViewCollection}"   RowDetailsVisibilityMode="Collapsed" 
              SelectedItem="{Binding SelectedItemRow, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
              AutoGenerateColumns="False">
                <DataGrid.Columns>
                    <DataGridTemplateColumn>
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <DockPanel HorizontalAlignment="Stretch">
                                    <ToggleButton x:Name="btnEditItem" Content="Edit" Width="50" Height="20" Margin="0 0 3 0"                                    
                                    Command="{Binding RelativeSource={RelativeSource AncestorType=DataGrid}, Path=DataContext.UpdateItemCommand}" 
                                    CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=DataGridRow}, Path=DataContext}"/>
                                </DockPanel>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                    <DataGridTextColumn x:Name="gr" Binding="{Binding Group}" Header="Gr" Width="30"   />
                    <DataGridTextColumn x:Name="one" Binding="{Binding Col_1}" Header="h1" Width="30"   />
                    <DataGridTextColumn x:Name="two" Binding="{Binding Col_2}" Header="h2" Width="30"  />
                    <DataGridTextColumn x:Name="tree" Binding="{Binding Col_3}" Header="h3" Width="30" />
                </DataGrid.Columns>
            </DataGrid>
        </StackPanel>
    </Grid>
</Window>

代码隐藏

namespace TotalRows
{

    public class ItemClass
    {
        public int Group { get; set; }
        public string Title { get; set; }

        public int Col_1 { get; set; }
        public int Col_2 { get; set; }
        public int Col_3 { get; set; }
    }

    public class ExampleData
    {
        private bool _IsReadMode;
        public bool IsReadMode
        {
            get { return _IsReadMode; }
            set
            {
                _IsReadMode = value;
                OnPropertyChanged(nameof(IsReadMode));
            }
        }

        private ItemClass _selectedItem = null;
        public ItemClass SelectedItemRow
        {
            get { return _selectedItem; }
            set
            {
                _selectedItem = value;
                OnPropertyChanged(nameof(SelectedItemRow));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        private ObservableCollection<ItemClass> _items;
        public ObservableCollection<ItemClass> Items
        {
            get
            {
                return _items;
            }
            set
            {
                if (_items != value)
                {
                    _items = value;
                    OnPropertyChanged(nameof(Items));

                }
            }
        }

        private ICollectionView _itemsViewCollection;
        public ICollectionView ItemsViewCollection
        {
            get
            {
                return _itemsViewCollection;
            }
            set
            {
                if (_itemsViewCollection != value)
                {
                    _itemsViewCollection = value;
                    OnPropertyChanged(nameof(ItemsViewCollection));
                }
            }
        }
        
        public ICommand UpdateItemCommand { get; private set; }

        public ExampleData()
        {
            IsReadMode = true;
            UpdateItemCommand = new ViewModelCommand(param => updateItemCommand(param));

            Items = new ObservableCollection<ItemClass>()
            {
              new ItemClass() {Group=1, Title="Item1", Col_1=100, Col_2=150, Col_3=250},

              new ItemClass() {Group=2, Title="Item1", Col_1=50, Col_2=2, Col_3=200},
              new ItemClass() {Group=2, Title="Item2", Col_1=50, Col_2=100, Col_3=40},

              new ItemClass() {Group=3, Title="Item1", Col_1=60, Col_2=25, Col_3=230},
              new ItemClass() {Group=3, Title="Item2", Col_1=30, Col_2=25, Col_3=0},
              new ItemClass() {Group=3, Title="Item3", Col_1=9, Col_2=100, Col_3=20},

              new ItemClass() {Group=4, Title="Item1", Col_1=46, Col_2=32, Col_3=30},
          };

          ItemsViewCollection = CollectionViewSource.GetDefaultView(Items);
          ItemsViewCollection.GroupDescriptions.Add(new PropertyGroupDescription("Group"));

      }
      private void updateItemCommand(object param)
      {
        IsReadMode = !IsReadMode;
    }
  }
}
68bkxrlz

68bkxrlz1#

你知道按f2键会把当前行切换到编辑模式吗?

CommandManager.RegisterClassInputBinding(ownerType, new InputBinding(BeginEditCommand, new KeyGesture(Key.F2))); 
        CommandManager.RegisterClassCommandBinding(ownerType, new CommandBinding(BeginEditCommand, new ExecutedRoutedEventHandler(OnExecutedBeginEdit), new CanExecuteRoutedEventHandler(OnCanExecuteBeginEdit)));

您可以将编辑按钮绑定到ExampleData视图模型中的命令,并将对特定ItemClass的引用作为命令参数传递。
使用相对源绑定来获取该命令。
ExampleData拥有这个集合,所以你可以在这个示例上设置属性,并隐藏一个引用或索引,指向他们最后编辑的一个示例,或者把标志设置回去,或者遍历整个集合。
看起来你知道如何写命令,但我推荐社区mvvm工具包和relaycommand。
你的绑定应该是

<Button Command="{Binding DataContext.EditThisOneCommand  
                            , RelativeSource={RelativeSource AncestorType=DataGrid}}"
                              CommandParameter="{Binding}">

command参数将该行传递给Icommand,因此将是传递给命令的参数。
我也有类似的命令。

private RelayCommand<Thing> _colourCommand;
    public RelayCommand<Thing> ColourCommand
    {
        get
        {
            return _colourCommand
              ?? (_colourCommand = new RelayCommand<Thing>(
                _thing =>
                {
                    _thing.Row = Items.IndexOf(_thing);
                },
                 _thing =>  CanUserClick));
        }
    }

当然,您可以使用EditThisOneCommand
然后,您必须告诉UI发出BeginEditCommand。
然后,您需要告诉UI在完成时发出CommitEditCommand。

CommandManager.RegisterClassCommandBinding(ownerType, new CommandBinding(CommitEditCommand, new ExecutedRoutedEventHandler(OnExecutedCommitEdit), new CanExecuteRoutedEventHandler(OnCanExecuteCommitEdit)));

这些命令来自数据网格。
您可以只将这些datagrid命令绑定到按钮,而不使用此标志。
一个datagridrow有一个属性IsEditing。你可以把这个onewaytosource绑定到你的flag上。你可以通过一个样式来设置这个绑定。不知道你为什么要这么做,但是你可以看看这个。
https://learn.microsoft.com/en-us/dotnet/api/system.windows.controls.datagridrow.isediting?view=windowsdesktop-7.0

相关问题