Reputation: 161
Friends, I am creating one small application in WPF C# with following MVVM structure.
I am stuck to one point where even I don't know how to google it, so finally thought to keep it here.
You can see from below image that I have a table structure using GridView
. I have enabled a single cell selection also in the same.
Now what I need is when I click on particular cell, TextBox named as AllowEdit_Text
should show value of selected text, and once I edit in this TextBox, it should reflect back to table. Now what my worry is how to get access of the individual cell which is selected?(Even my table is Dynamic). I found many articles like the link here: How do i handle cell double click event on WPF DataGrid, equivalent to windows DataGrid's Events?
But in these articles they all use back-end method with Sender argument, which can be accessible in coding part of View only, but as this one is violating MVVM structure, I am confused how to proceed. Please show me the perfect way which can be helpful and also follows MVVM structure.
Below is my existing View code for your reference.
VehicalForm.xaml
<Window x:Class="Seris.VehicalForm"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="500" Width="600">
<Control>
<Control.Template>
<ControlTemplate>
<WrapPanel Orientation="Vertical" Margin="10 " >
<Label Content="Vehical No" HorizontalAlignment="Left"/>
<TextBox Name="VehicalNo_Text" Height="23" Width="80" TextWrapping="Wrap" Text="{Binding VehicalNo, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" />
<Label Content="Model" HorizontalAlignment="Left"/>
<TextBox Name="Model_Text" Height="23" Width="80" TextWrapping="Wrap" Text="{Binding Model, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" />
<Label Content="Manufacturing Date" HorizontalAlignment="Left"/>
<DatePicker Name="ManufacturingDate_DateTime" SelectedDate="{Binding ManufacturingDate, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
<Label Content="IU No" HorizontalAlignment="Left"/>
<TextBox Height="23" Width="80" Name="IUNO_Text" TextWrapping="Wrap" Text="{Binding IUNo, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left"/>
<Label Content="Personnel" HorizontalAlignment="Left"/>
<ComboBox Name="Personnel_Combo" SelectedValue="{Binding PersonnelNameSelected, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding PersonnelName, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" HorizontalAlignment="Left" Width="116"/>
<Separator Height="20" RenderTransformOrigin="0.5,0.5" Width="16"/>
<Button Name="Save_Button" Command="{Binding SaveButton_Command}" Content="Save" Width="66"/>
<Label x:Name="Error_Label" Content="{Binding ErrorMessage, UpdateSourceTrigger=PropertyChanged}" Foreground="Red" HorizontalAlignment="Left" Height="41" Width="137"/>
<ListView Name ="Grid" Height="294" Width="371" >
<DataGrid Name="DG" ItemsSource="{Binding ListItems, UpdateSourceTrigger=PropertyChanged}" SelectionUnit="Cell" GridLinesVisibility="None" IsReadOnly="True" AutoGenerateColumns="False" BorderThickness="0">
<DataGrid.Columns>
<DataGridTextColumn Header="Vehical No" Binding="{Binding VehicalNo}" />
<DataGridTextColumn Header="Model" Binding="{Binding Model}" />
<DataGridTextColumn Header="ManufacturingDate" Binding="{Binding ManufacturingDate}" />
<DataGridTextColumn Header="IUNo" Binding="{Binding IUNo}" />
<DataGridTextColumn Header="Personnel" Binding="{Binding PersonnelNameSelected, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
</DataGrid.Columns>
</DataGrid>
</ListView>
<TextBlock Name="Notification" Text="{Binding EditText, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Name="AllowEdit_Text"/>
</WrapPanel>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding IsMouseOver, ElementName=Grid}" Value="true">
<Setter Property="Text" TargetName="Notification" Value="abc"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Control.Template>
</Control>
</Window>
Upvotes: 1
Views: 6284
Reputation: 388
It's better to use MVVMLight. I give you the steps to retrieve the selected row(s) of the grid.
1. First of all the datagrid binding
XAML
<DataGrid ItemsSource="{Binding friends}" AutoGenerateColumns="False">
Code Behind
private ObservableCollection<Friend> _friends;
public ObservableCollection<Friend> friends
{
get { return _friends; }
set { _friends = value;
RaisePropertyChanged(); }
}
2. The DataGrid click event, you can do that in different ways depending if you want to manage single row selection or multiple rows selection. In this case i show you how to manage multiple selection, it can be used also for single row selection or you can use the SelectedItem Property of the grid.
References to add to the view to be able to use the MVVMLight events
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:MVVVMLightCommand="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Platform"
Manage the event on the datagrid for the "MouseDoubleClick" event
<DataGrid ItemsSource="{Binding ItemSourceDataGrid}" x:Name="dataGridTest" AutoGenerateColumns="False" Height="258" Width="485" Grid.Column="1">
....
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick" >
<MVVVMLightCommand:EventToCommand Command="{Binding DGSelectionChangedCommand,Mode=OneWay}" CommandParameter="{Binding SelectedItems, ElementName=DataGridTest}" />
</i:EventTrigger>
</i:Interaction.Triggers>
...
</DataGrid>
Constructor of the viewmodel, as you can see the RelayCommand will receive a list of objects correspoding to the selected rows.
DGSelectionChangedCommand = new RelayCommand<IList>(DGSelectionChanged);
Viewmodel - The RelayCommand
public RelayCommand<IList> DGSelectionChangedCommand { get; private set;}
Viewmodel - where you retrieve the list<> of selected rows.
private void DataGridSelectionChanged(IList test)
{
foreach (var item in test)
{
MessageBox.Show(((Friend)item).ID.ToString());
}
}
Hope this helps
Upvotes: 0
Reputation: 88
Use SelectedIndex property in following way
<DataGrid
Name="DG"
ItemsSource="{Binding ListItems, UpdateSourceTrigger=PropertyChanged}"
SelectedIndex="{Binding SelectedIndex, Mode=TwoWay}"
SelectionUnit="Cell"
GridLinesVisibility="None"
IsReadOnly="True"
AutoGenerateColumns="False"
BorderThickness="0">
Using this property you can get the selected index in the grid.
Upvotes: 0
Reputation: 606
You can use the MVVMLight framework to use EventToCommand behavior. Example:
<ListBox Name="list">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<Command:EventToCommand
Command="{Binding Path=DataContext.DoSomethingCommand,ElementName=list}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ListBox>
Upvotes: 1