【问题标题】:Datagrid not adding a new row by pressing Enter or TabDatagrid 不按 Enter 或 Tab 添加新行
【发布时间】:2014-04-09 13:35:18
【问题描述】:

我有一个数据网格,其中CanUserAddRows = "true"

当我运行程序时,我得到一个空白行。当我在该行中输入数据时,它工作得很好。但是在那之后,如果我尝试添加新行,我将无法添加它,因为按 EnterTAB 没有得到空白行。

这是我的数据网格所在的页面:

<Page x:Class="WPF_Client.Pages.Masters.Multiple.Groups"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:helpers="clr-namespace:WPF_Client.HelperClasses"
      xmlns:vm="clr-namespace:WPF_Client.ViewModels.Masters.Multiple"
      mc:Ignorable="d" 
      d:DesignHeight="760" d:DesignWidth="1366"
      Title="Groups">

    <Page.DataContext>
        <vm:GroupsViewModel />
    </Page.DataContext>

    <Page.Resources>
        <CollectionViewSource x:Key="GroupNamesWithCorrespondingEffectsCollection" Source="{Binding GroupNamesWithCorrespondingEffects}" />
    </Page.Resources>

    <Grid>
        <DataGrid CanUserAddRows="True" CanUserReorderColumns="False" CanUserSortColumns="False" CanUserDeleteRows="True"
                  ItemsSource="{Binding Groups}" AutoGenerateColumns="False">
            <DataGrid.Resources>
                <CompositeCollection x:Key="Items">
                    <ComboBoxItem IsEnabled="False" Background="#FF2A2A2A" Foreground="White">
                        <Grid TextElement.FontWeight="Bold" >
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition SharedSizeGroup="A" />
                                <ColumnDefinition Width="50" />
                                <ColumnDefinition SharedSizeGroup="B" />
                            </Grid.ColumnDefinitions>
                            <Grid.Children>
                                <TextBlock Grid.Column="0" Text="Group Name" />
                                <TextBlock Grid.Column="2" Text="Effect" />
                            </Grid.Children>
                        </Grid>
                    </ComboBoxItem>
                    <CollectionContainer Collection="{Binding Source={StaticResource GroupNamesWithCorrespondingEffectsCollection}}" />
                </CompositeCollection>

                <DataTemplate DataType="{x:Type helpers:GroupNameWithCorrespondingEffect}">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition SharedSizeGroup="A" />
                            <ColumnDefinition Width="50" />
                            <ColumnDefinition SharedSizeGroup="B" />
                        </Grid.ColumnDefinitions>
                        <Grid.Children>
                            <TextBlock Grid.Column="0" Text="{Binding GroupName}" />
                            <TextBlock Grid.Column="2" Text="{Binding CorrespondingEffect}" />
                        </Grid.Children>
                    </Grid>
                </DataTemplate>
            </DataGrid.Resources>
                <DataGrid.Columns>
                <DataGridTemplateColumn Header="Name" Width="2*">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox Text="{Binding GroupName}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTemplateColumn Header="Group" Width="2*">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox ItemsSource="{DynamicResource Items}" 
                                      SelectedValue="{Binding DataContext.SelectedGroupID, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Page}}}"
                                      SelectedValuePath="GroupID" Grid.IsSharedSizeScope="True" TextSearch.TextPath="GroupName">
                            </ComboBox>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTemplateColumn Header="Effect" Width="*" >
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox ItemsSource="{Binding DataContext.Effects, RelativeSource={RelativeSource AncestorType={x:Type Page}}}" DisplayMemberPath="Effect" 
                                                            SelectedValue="{Binding DataContext.SelectedEffectID, RelativeSource={RelativeSource AncestorType={x:Type Page}}}" SelectedValuePath="EffectID"
                                      Visibility="{Binding Path=DataContext.SelectedGroupID, 
                                                             RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Page}},
                                                             Converter={StaticResource effectsVisibilityConverter}}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>

</Page>

这是我的视图模型:

public class GroupsViewModel : ViewModelBase, IModule
{
    public GroupsViewModel()
    {
        SessionViewModel.Instance.ModulesOpen.Add((IModule)this);

        Groups = new ObservableCollection<Group>();

        using (Entities db = new Entities())
        {
            List<GroupNameWithCorrespondingEffect> _GroupNamesWithCorrespondingEffects = (
                                                                                             from g in db.Groups
                                                                                             select new GroupNameWithCorrespondingEffect
                                                                                             {
                                                                                                 GroupID = g.GroupID,
                                                                                                 GroupName = g.GroupName,
                                                                                                 CorrespondingEffect = g.Master_Effects.Effect
                                                                                             }
                                                                                         ).ToList();

            GroupNamesWithCorrespondingEffects
                = new ObservableCollection<GroupNameWithCorrespondingEffect>(
                                                                                _GroupNamesWithCorrespondingEffects.Where
                                                                                    (
                                                                                        u => !StaticMethods.GetAllChildren(25)
                                                                                                .Select(x => x.GroupID)
                                                                                                .Contains(u.GroupID)
                                                                                    ).ToList()
                                                                            );

            Effects = new ObservableCollection<Master_Effects>(from m in db.Master_Effects
                                                               select m);
        }
    }

    ~GroupsViewModel()
    {
        SessionViewModel.Instance.ModulesOpen.Remove((IModule)this);
    }

    private ObservableCollection<Group> _groups;
    public ObservableCollection<Group> Groups
    {
        get
        {
            return _groups;
        }
        set
        {
            _groups = value;
            OnPropertyChanged("Groups");
        }
    }

    private ObservableCollection<GroupNameWithCorrespondingEffect> _groupNamesWithCorrespondingEffects;
    public ObservableCollection<GroupNameWithCorrespondingEffect> GroupNamesWithCorrespondingEffects
    {
        get
        {
            return _groupNamesWithCorrespondingEffects;
        }
        set
        {
            _groupNamesWithCorrespondingEffects = value;
            OnPropertyChanged("GroupNamesWithCorrespondingEffects");
        }
    }

    private int _selectedGroupID;
    public int SelectedGroupID
    {
        get
        {
            return _selectedGroupID;
        }
        set
        {
            _selectedGroupID = value;
            OnPropertyChanged("SelectedGroupID");
        }
    }

    private ObservableCollection<Master_Effects> _effects;
    public ObservableCollection<Master_Effects> Effects
    {
        get
        {
            return _effects;
        }
        set
        {
            _effects = value;
            OnPropertyChanged("Effects");
        }
    }

    private int _selectedEffectID;
    public int SelectedEffectID
    {
        get
        {
            return _selectedEffectID;
        }

        set
        {
            _selectedEffectID = value;
            OnPropertyChanged("SelectedEffectID");
        }
    }

    public string ModuleFriendlyName
    {
        get { return "GroupsViewModel"; }
    }

    public string ModuleName
    {
        get { return "Groups"; }
    }
}

我做错了吗?还是dataGrid的默认行为?

更新:

我已根据您的建议更新了我的代码。这是我的 xaml:

<DataGrid ..............>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="PreviewKeyDown">
            <i:InvokeCommandAction Command="{Binding DataContext.NewRowCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Page}}}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</DataGrid>

这是我的视图模型:

//在构造函数中: NewRowCommand = new RelayCommand(NewRow);

//在正文中:

public ICommand NewRowCommand { get; set; }

private void NewRow(object obj)
{
    MessageBox.Show("PreviewKeyDown on Datagrid invoked.");
}

当我在 DataGrid 的输入区域按任意键时,我成功地在输出中获得 MessageBox。

更新后的问题:

现在,在尝试了你的建议之后,我也遇到了一些问题。

我只想在按 Enter 时显示该消息框(如果它是网格上的默认行为。我不知道默认行为,因为我对 DataGrid 非常陌生。)键在数据网格上。所以,我的实际问题是识别按下的键。

【问题讨论】:

    标签: c# wpf xaml datagrid


    【解决方案1】:

    您必须将击键事件“路由”到某个 ViewModel 方法,以便将新项目添加到集合中。在此类方法结束时,您必须调用 OnPropertyChanged 以在视图中反映新项目。

    编辑

    1. 引用程序集 System.Windows.Interactivity
    2. xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 添加到您的 xaml 声明中
    3. 使用它:

    <i:Interaction.Triggers> <i:EventTrigger> </i:EventTrigger> </i:Interaction.Triggers>

    更多详情请查看此链接:

    Here here

    编辑 2:

    我看到了问题,InputBindings 会在这种情况下完成这项工作:

    <DataGrid.InputBindings>
        <KeyBinding Key="Enter" Command="{Binding NewRowCommand }"/>
    </DataGrid.InputBindings>
    

    【讨论】:

    • 感谢您的建议。你能告诉我任何例子或教程吗?另外,正如你所说我应该路由击键,那么你能解释一下 DataGrid 的 CanUserAddRows 属性的用途吗?
    • 感谢您的更新。它帮助了我。现在我使用了 PreviewKeyDown 事件并将命令绑​​定到它。我会用最新的更新来更新我的代码。
    猜你喜欢
    • 2016-08-17
    • 1970-01-01
    • 2019-11-20
    • 2015-04-06
    • 2014-09-11
    • 1970-01-01
    • 1970-01-01
    • 2012-08-06
    • 2016-10-29
    相关资源
    最近更新 更多