Spi*_*osi 5 wpf datagrid combobox mvvm datagridtemplatecolumn
我有一个DataGrid具有DataGridTemplateColumn和ComboBox它.
<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单击空行即可获取数据?
如果您需要通过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.Interactions和System.Windows.Interactivity库的引用。然后我将EventTrigger和CallMethodAction添加到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。