Allready have a two classes in master detail schema,
the master class has a collection of detail master, and need (want) to perform all crude options inline.
Classes:
public partial class Items
{
public Items()
{
this.Detail = new HashSet<Detail>();
}
public decimal NumIdConcepto { get; set; }
public string StrDescripcionConcepto { get; set; }
public virtual ICollection<Detail> Detail { get; set; }
}
public partial class Detail
{
public int IntTipoAsociado { get; set; }
public decimal NumIdConcepto { get; set; }
public virtual Items Items { get; set; }
public virtual Master Master { get; set; }
}
public partial class Master
{
public Master()
{
this.Detail = new HashSet<Detail>();
}
public int IntTipoAsociado { get; set; }
public string StrDescripcionTipoAsociado { get; set; }
public virtual ICollection<Detail> Detail { get; set; }
}
For editing purposes and limitations of EF generator must perform a conversion from HashSet to ObservableCollection for Detail collection of Master
public class listToObservableCollection : BaseConverter, IValueConverter
{
public HashSet<Detail> JustForPath { get; set; }
public ObservableCollection<Detail> JustForPathObservable { get; set; }
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
HashSet<Detail> observableList = (HashSet<Detail>)value;
JustForPathObservable = new ObservableCollection<Detail>(observableList);
return JustForPathObservable;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
JustForPath = (HashSet<Detail>)value;
return JustForPath;
}
}
public abstract class BaseConverter : MarkupExtension
{
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
With this structure I want to generate a DataGrid wich allow me to add, delete, and edit Detail In line, Don't want to call another forms
Like this:
My XAML code look like this:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ViewModels="clr-namespace:Contratos.ViewModels" x:Class="Contratos.Views.TipoAsociado"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF45"
xmlns:l="clr-namespace:Recursos;assembly=Recursos"
Title="{Binding Title}" Height="Auto" Width="Auto">
<Window.DataContext>
<ViewModels:TipoAsociadoVM/>
</Window.DataContext>
<Window.Resources>
<l:listToObservableCollection x:Key="listoToObservable"/>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<DataGrid Grid.Row="1"
ItemsSource="{Binding Master}"
AutoGenerateColumns="False"
SelectionMode="Single"
GridLinesVisibility="Vertical"
CanUserAddRows="True"
CanUserDeleteRows="True"
x:Name="GridTipoAsociado"
Margin="5" SelectionChanged="GridTipoAsociado_SelectionChanged">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<cmd:EventToCommand Command="{Binding _ICommandSelectionChange}"
PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<DataGrid.Columns>
<DataGridTemplateColumn Header="Description" x:Name="Description">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Label Content="{Binding StrDescripcionTipoAsociado}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<TextBox Text="{Binding StrDescripcionTipoAsociado }"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<DataGrid Grid.Row="1"
ItemsSource="{Binding Path=Detail,Converter={StaticResource listoToObservable},Mode=TwoWay}"
DisplayMemberPath="StrDescripcionConcepto"
AutoGenerateColumns="False"
IsSynchronizedWithCurrentItem="True"
SelectionMode="Single"
SelectionUnit="Cell"
GridLinesVisibility="Vertical"
CanUserAddRows="True"
CanUserDeleteRows="True"
x:Name="GridItems"
Margin="20,5,5,5">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Items">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Label Content="{Binding Items.StrDescripcionConcepto}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<!--
Here is my problem How can i to bind to the propper values to perform Editing
Without having this exception "TWO WAY BINDING REQUIRES PATH OR XPATH" when try to update DETAIL items:
-->
<TextBox Text="{Binding Items.StrDescripcionConcepto}"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
</Grid>
</Window>
Now, I need help on how to build a propper CellEditingTemplate, to allow me edit all the changes that i need ?
Here is my problem How can i to bind to the propper values to perform Editing Without having this exception "TWO WAY BINDING REQUIRES PATH OR XPATH" when try to update DETAIL items?
NOTE: I don't want to create new Items, here, Just attach it to Detail
Finally found my problem and of course the solution.
The binding must be relative to the datacontext of the window instead relative to it's parent, in this case DataGrid
I'm redefining the datacontext of the window as a static resource, then I reuse it for my elements that need access to the global properties of my model, Grid and CellEditingTemplate
<Window.Resources>
<ViewModels:ViewModel x:Key="ViewDataContext"/>
</Window.Resources>
<!-- Here I use Static resource as Data context -->
<Grid DataContext="{Binding Source={StaticResource ResourceKey=ViewDataContext}}">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Tipo de asociado" x:Name="TipoUsuarioSeleccionado">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Label Content="{Binding SomeElement}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<!-- Again I use Static resource as Data context -->
<Grid Height="130" DataContext="{Binding Source={StaticResource ViewDataContext}}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<TextBox x:Name="Filtro" Text="{Binding SomeInViewModel}"/>
<ListView Grid.Row="1" ItemsSource="{Binding ListaItems}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding SomeinVM}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</Grid>