WPF Datagrid-如何强制在行中提交数据?

问题描述 投票:-1回答:1

[当数据网格行失去焦点而不是要求用户按回车键来提交时,如何强制提交?

我有一个MVVM项目,其主DataGrid使用的RowDetailsTemplate包含另一个子DataGrid。它使用在行上按“ Enter”的默认行为来提交值更改。我为主行和子行都实现了ValidatonRule

子网格已关闭enter image description here

子网格已打开enter image description here

  • 从组合框中选择一个帐户会在主网格中填充交易。单击[Sub]按钮将打开子网格并显示该事务的子事务。
  • 如果用户在交易记录(主行)中输入值并按'Enter',则交易记录值已成功提交;即触发了Transaction ValdationStep.CommittedValue
  • [如果用户在主行中输入值(不按'Enter'),只需单击[Subs]按钮以打开子网格,然后在子事务中输入值并按'Enter',则子事务值为成功承诺;即触发了SubtransactionValidation ValdationStep.CommittedValue
  • 但是如果用户随后在未按主行上的“ Enter”键的情况下从子网格中单击,则事务中的值将被提交。即,Transaction ValdationStep.CommittedValue被触发。然后,当选择一个新帐户时(导致ItemsSource集合发生更改),CollectionChanged上会触发一个ItemsSource事件,以删除源项目(未提交的交易),就像用户点击了“ Esc”一样。[我假设CollectionChanged事件是由DataGrid决定尚未提交的行触发的,因此将其从集合中删除。
  • SO: Cancel collection changed event on an observable collection可能是取消CollectionChanged和删除项目的一种方法,但似乎更需要强制提交更改。另外,我必须弄清楚何时启用/禁用何时忽略事件。

[我以为这个SO: wpf Datagrid force datagrid row evaluation可能是一个解决方案(虽然过大了),并在按钮代码中实现了它(请参见下文),但是当我选择其他帐户和[ C0]集合已更改。

CollectionChanged

然后我尝试捕获ItemsSource(我发现该事件是在单击[Subs]按钮后触发的)并在该行上强制private void ToggleSubs_Click(object sender, RoutedEventArgs e) { ... foreach (var item in BankDataGrid.ItemContainerGenerator.Items) { var container = BankDataGrid.ItemContainerGenerator.ContainerFromItem(item); if (container != null && container is DataGridRow dgr) { dgr.BindingGroup.CommitEdit(); } } } 。但是,当我选择其他帐户时,再次触发了ValidationStep.ConvertedProposedValue事件以删除该项目。

XAML

BindingGroup.CommitEdit()

MainVM

CollectionChanged

用于交易收集的AccountVM CollectionChanged处理程序

<Grid>
    <Grid x:Name="MainPanel">
        <Grid.RowDefinitions>
            <RowDefinition Height="26" />
            <RowDefinition Height="30" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        ...
        <Grid x:Name="Controls" Grid.Row="1" >
            ...
            <StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Left">
                <Label Content="Account" VerticalAlignment="Center" />
                <ComboBox Name="ControlsAccount" VerticalAlignment="Center" Width="210"
                          ItemsSource="{Binding AccountList}" 
                          SelectedItem="{Binding SelectedAccount}"
                          IsEnabled="{Binding HasAccounts}" >
                    <ComboBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Name}" 
                                Foreground="{Binding ItemForeColor}" 
                                Background="{Binding ItemBackColor}" />
                        </DataTemplate>
                    </ComboBox.ItemTemplate>
                </ComboBox>
            </StackPanel>
            ...
        </Grid>
        <DataGrid x:Name="BankDataGrid" Grid.Row="2"
            ItemsSource="{Binding SelectedAccount.Transactions, UpdateSourceTrigger=LostFocus}"
            SelectedItem="{Binding SelectedAccount.SelectedTransaction, Converter={StaticResource TransConverter}}" >
            ...
            <DataGrid.RowValidationRules>
                <valid:BankTransactionValidation ValidationStep="UpdatedValue" />
                <valid:BankTransactionValidation ValidationStep="CommittedValue" />
            </DataGrid.RowValidationRules>
            ...
            <DataGrid.Columns>
                ...
            </DataGrid.Columns>

            <DataGrid.RowDetailsTemplate>
                <DataTemplate x:Name="SubDataTemplate">
                    <DataGrid x:Name="SubDataGrid"
                        ItemsSource="{Binding Subtransactions}"
                        SelectedItem="{Binding SelectedSubtransaction, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource SubtransConverter}}" >
                        ...
                        <DataGrid.RowValidationRules>
                            <valid:SubtransactionValidation ValidationStep="UpdatedValue" />
                            <valid:SubtransactionValidation ValidationStep="CommittedValue" />
                        </DataGrid.RowValidationRules>
                        ...
                        <DataGrid.Columns>
                            ...
                        </DataGrid.Columns>
                    </DataGrid>
                </DataTemplate>
            </DataGrid.RowDetailsTemplate>
        </DataGrid>
    </Grid>
    ...
</Grid>

BankTransactionValidation

partial class MainVM : BaseVM
{
    public MainVM()
    {
        LoadSettings();

        InitMainPanel();
        InitTransactionSearch();
        InitLookupMaintenance();
        InitLookupReplacement();
        InitAccountDetails();
        InitBusyPanel();
    }
    ...
    private ObservableCollection<AccountVM> accountList;
    public ObservableCollection<AccountVM> AccountList
    {
        get => accountList;
        set
        {
            accountList = value;
            NotifyPropertyChanged();
        }
    }
    private AccountVM selectedAccount;
    public AccountVM SelectedAccount
    {
        get => selectedAccount;
        set
        {
            selectedAccount = value;
            NotifyPropertyChanged();
            if (selectedAccount != null)
            {
                WindowTitle = $"{selectedAccount.Name} - {AppName}";
                BankDataGridVisibility = VISIBILITY_SHOW;
                BackgroundImageVisibility = VISIBILITY_HIDE;
                SubtransactionsVisibility = VISIBILITY_COLLAPSE;
                SubtransactionVM.XferAccountRemove(selectedAccount.Name, AccountList);
            }
            else
            {
                HideTransactions();
            }
            HasAccounts = (AccountList != null && AccountList.Count > 0) ? LITERAL_TRUE : LITERAL_FALSE;
        }
    }
    ...
}

当数据网格行失去焦点而不是要求用户按回车键进行提交时,如何强制提交?我有一个使用RowDetailsTemplate的带有主DataGrid的MVVM项目,它具有...

wpf datagrid commit itemssource
1个回答
0
投票
public class BankTransactionValidation : ValidationRule { public override ValidationResult Validate(object value, CultureInfo cultureInfo) { var result = ValidationResult.ValidResult; var bg = (BindingGroup)value; var row = (DataGridRow)bg.Owner; if (row.Item is BankTransactionVM item) { switch (ValidationStep) { case ValidationStep.RawProposedValue: break; case ValidationStep.ConvertedProposedValue: break; case ValidationStep.UpdatedValue: break; case ValidationStep.CommittedValue: if (item.TransactionId > 0) { item.Update(); if (item.Subtransactions.Count == 0) { item.Subtransactions.Add(new SubtransactionVM(item.TransactionId)); } } break; } } return result; } }
© www.soinside.com 2019 - 2024. All rights reserved.