If you need to get data in the ComboBox
with a single click on blank row, I suggest you to use Caliburn.Micro to "attach" a command to the DropDownOpened
event of your ComboBox
.
Here a sample: first of all the 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>
Then the ViewModel:
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; }
}
Please consider that in my sample the TestClass
code is the same that you wrote. Of course you must configure you application in order to work with Caliburn.Micro (if you do not know how to do it, you can read the documentation).
If you do not want (or maybe you cannot) use Caliburn.Micro, you can obtain the same result by using the System.Windows.Interactivity library (see my edit below).
Try the code: just a click and a new row is automatically created.
I hope it can help you.
EDIT:
alternative solution with System.Windows.Interactivity
If you cannot use Caliburn.Micro, you just need to modify the MainView XAML in this way:
<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>
As you can see, I just added the references to Microsoft.Expression.Interactions and System.Windows.Interactivity libraries. Then I added an EventTrigger and a CallMethodAction to the ComboBox
.
Now in the MainViewModel
you can replace the Choose
method with the ChooseWithInteraction
one (of course you can also simply add it to the code):
public void ChooseWithInteraction(object sender, EventArgs args)
{
object data = ((ComboBox)sender).DataContext;
if (!(data is TestClass))
{
TestItemCollection.Add(new TestClass());
}
}
In this way you can obtain the same behaviour of my first solution, but without using Caliburn.