WPF DataGrid单击以创建新项

Spi*_*osi 5 wpf datagrid combobox mvvm datagridtemplatecolumn

我有一个DataGrid具有DataGridTemplateColumnComboBox它.

<DataGrid GridLinesVisibility="All" AutoGenerateColumns="False" ItemsSource="{Binding TestItemCollection}">
        <DataGrid.Columns>
            <DataGridTemplateColumn Width="*" Header="Test Column">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox Width="150"
                                  HorizontalAlignment="Left"
                                  ItemsSource="{Binding TestChildCollection}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>



public ObservableCollection<TestClass> TestItemCollection { get; set; } = new ObservableCollection<TestClass>
    {
        new TestClass(),
        new TestClass(),
        new TestClass(),
    };

    public class TestClass
    {
        public ObservableCollection<string> TestChildCollection { get; set; } = new ObservableCollection<string>
        {
            "First test item", "Second test item" , "Third test item" , "Fourth test item" 
        };
    }
Run Code Online (Sandbox Code Playgroud)

当我单击ComboBox空白行时,它显然不会创建我的集合的新实例,只给出一个空白列表.

在此输入图像描述

我必须双击空行空间.

在此输入图像描述

只有这样我才能获得数据ComboBox.

在此输入图像描述

如何只需Combobox单击空行即可获取数据?

Il *_*Vic 1

如果您需要通过ComboBox单击空白行来获取数据,我建议您使用Caliburn.Micro将命令“附加”到DropDownOpened您的ComboBox.

这是一个示例:首先是 XAML

<Window x:Class="WpfApplication1.MainView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:cal="http://www.caliburnproject.org"
        Title="MainView" Height="600" Width="600"
        Name="_window">

    <DataGrid GridLinesVisibility="All" AutoGenerateColumns="False" ItemsSource="{Binding TestItemCollection}">
        <DataGrid.Columns>
            <DataGridTemplateColumn Width="*" Header="Test Column">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox Width="150"
                                    HorizontalAlignment="Left"
                                    ItemsSource="{Binding TestChildCollection}"
                                    cal:Message.Attach="[Event DropDownOpened] = [Action Choose($dataContext)]"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
Run Code Online (Sandbox Code Playgroud)

然后是视图模型:

public class MainViewModel : Caliburn.Micro.PropertyChangedBase
{
    public MainViewModel()
    {
        TestItemCollection = new ObservableCollection<TestClass>
        {
            new TestClass(),
            new TestClass(),
            new TestClass(),
        };
    }

    public void Choose(object data)
    {
        if (!(data is TestClass))
        {
            TestItemCollection.Add(new TestClass());
        }
    }

    public ObservableCollection<TestClass> TestItemCollection { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

请考虑在我的示例中,TestClass代码与您编写的代码相同。当然,您必须配置应用程序才能使用 Caliburn.Micro(如果您不知道如何操作,可以阅读文档

如果您不想(或者可能不能)使用 Caliburn.Micro,则可以使用System.Windows.Interactivity库获得相同的结果(请参阅下面我的编辑)。

尝试代码:只需单击一下,就会自动创建一个新行。我希望它可以帮助你。

编辑:使用 System.Windows.Interactivity的替代解决方案

如果你不能使用Caliburn.Micro,你只需要这样修改MainView XAML:

<Window x:Class="WpfApplication1.MainView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
        Title="MainView" Height="600" Width="600"
        Name="_window">

    <DataGrid GridLinesVisibility="All" AutoGenerateColumns="False" ItemsSource="{Binding TestItemCollection}">
        <DataGrid.Columns>
            <DataGridTemplateColumn Width="*" Header="Test Column">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox Width="150"
                                  HorizontalAlignment="Left"
                                  ItemsSource="{Binding TestChildCollection}">
                            <i:Interaction.Triggers>
                                <i:EventTrigger EventName="DropDownOpened">
                                    <ei:CallMethodAction MethodName="ChooseWithInteraction"
                                                         TargetObject="{Binding ElementName=_window, Path=DataContext}" />
                                </i:EventTrigger>
                            </i:Interaction.Triggers>
                        </ComboBox>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>

</Window>
Run Code Online (Sandbox Code Playgroud)

如您所见,我刚刚添加了对Microsoft.Expression.InteractionsSystem.Windows.Interactivity库的引用。然后我将EventTriggerCallMethodAction添加到ComboBox.

现在,MainViewModel您可以将Choose方法替换为ChooseWithInteraction方法(当然您也可以简单地将其添加到代码中):

public void ChooseWithInteraction(object sender, EventArgs args)
{
    object data = ((ComboBox)sender).DataContext;
    if (!(data is TestClass))
    {
        TestItemCollection.Add(new TestClass());
    }
}
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以获得与我的第一个解决方案相同的行为,但不使用 Caliburn。