2013-09-02 26 views
15

Ho letto su questo almeno per 4 ore e sembra essere il tipo di elenco, ma ho una situazione:DataGrid edition 'EditItem' non è consentito per questa vista` quando associato a un WPF DataGrid

Una ObservableCollection che ha una proprietà collection.

ho definire il primo DataGrid, e nella sezione

<DataGrid.RowDetailsTemplate> 
    <DataTemplate> 
     <!-- second Datagrid here, binding to Level2 property of my Observable collection --> 
    </DataTemplate> 
<DataGrid.RowDetailsTemplate> 

tutto va bene, tutte le cose sullo schermo come mi aspettavo ... ma:

  1. Se tentare di modificare le cellule DataGrid1 IT permettimi.
  2. Se tentare di modificare le cellule DataGrid2 mi buttare questa eccezione 'EditItem' is not allowed for this view

Che cosa mi manca?

Questo è il mio modello:

public partial class Level1 
{ 
    public Level1() 
    { 
     this.Level2 = new HashSet<Level2>(); 
    } 

    public decimal IdLevel1 { get; set; } 
    public decimal IdLevel2 { get; set; } 
    public string StrDescripcionTipoAsociado {get;set;} 

    public virtual Level2 Level2{ get; set; } 
} 

public partial class Level2 
{ 
    public decimal IdLevel1 { get; set; } 
    public decimal IdLevel3 { get; set; } 

    public virtual Level3 Level3{ get; set; } 
} 

public partial class Level3 
{ 
    public decimal IdLevel3 { get; set; } 
    public decimal NumIdConcepto {get;set;} 
    public string StrDescripcionConcepto {get;set;} 
} 

EDIT: Codice XAML:

<DataGrid Grid.Row="1" 
       ItemsSource="{Binding Level1}" 
       AutoGenerateColumns="False" 
       SelectionMode="Single" 
       GridLinesVisibility="Vertical" 
       CanUserAddRows="True" 
       CanUserDeleteRows="True" 
       x:Name="GridTipoAsociado"> 
     <DataGrid.Columns> 
      <DataGridTemplateColumn Header="Tipo de asociado" x:Name="TipoUsuarioSeleccionado"> 
       <DataGridTemplateColumn.CellTemplate> 
        <DataTemplate> 
         <Label Style="{StaticResource ResourceKey=FontElemNivel1}" Content="{Binding StrDescripcionTipoAsociado}"/> 
        </DataTemplate> 
       </DataGridTemplateColumn.CellTemplate> 
       <DataGridTemplateColumn.CellEditingTemplate> 
        <DataTemplate> 
         <TextBox Style="{StaticResource ResourceKey=FontElemNivel2}" Text="{Binding StrDescripcionTipoAsociado }"/> 
        </DataTemplate> 
       </DataGridTemplateColumn.CellEditingTemplate> 
      </DataGridTemplateColumn> 
     </DataGrid.Columns> 
     <DataGrid.RowDetailsTemplate> 
      <DataTemplate> 
       <DataGrid Grid.Row="1" 
          ItemsSource="{Binding Level2}" 
          AutoGenerateColumns="False" 
          SelectionMode="Single" 
          SelectionUnit="Cell" 
          GridLinesVisibility="Vertical" 
          CanUserAddRows="True" 
          CanUserDeleteRows="True"        
          x:Name="GridItems"> 
        <DataGrid.Columns> 
         <DataGridTemplateColumn Header="Id Item"> 
          <DataGridTemplateColumn.CellTemplate> 
           <DataTemplate> 
            <Label Content="{Binding NumIdConcepto}"/> 
           </DataTemplate> 
          </DataGridTemplateColumn.CellTemplate> 
         </DataGridTemplateColumn> 
         <DataGridTemplateColumn Header="Items"> 
          <DataGridTemplateColumn.CellTemplate> 
           <DataTemplate> 
            <Label Content="{Binding Level3.StrDescripcionConcepto}"/> 
           </DataTemplate> 
          </DataGridTemplateColumn.CellTemplate> 
          <DataGridTemplateColumn.CellEditingTemplate> 
           <DataTemplate> 
            <TextBox Text="{Binding Level3.StrDescripcionConcepto}"/> 
           </DataTemplate> 
          </DataGridTemplateColumn.CellEditingTemplate> 
         </DataGridTemplateColumn> 
        </DataGrid.Columns> 
       </DataGrid> 
      </DataTemplate> 
     </DataGrid.RowDetailsTemplate> 
    </DataGrid> 
+0

potete inserire il codice XAML per DataGrid2 e il codice dietro per la sua collezione ItemsSource? – Nitin

+0

Sì, sto andando a pubblicare l'xaml, ma non ho alcun codice dietro. –

+0

Level3.StrDescripcionConcepto. dov'è questa proprietà? – Nitin

risposta

5

Tks per @nit che mi danno la strada giusta. Naturalmente il problema risiede sulla base Tipo di collezioni EF

Hashet < T> e hanno bisogno di Datagrid almeno un elenco < T>, cambiando tutte le mie classi "quelli generati da Entity Framework", dare a me un altro problema, è necessario apportare modifiche manualmente e ne ho molte.

La mia soluzione era quella di creare un convertitore, che ha fatto il lavoro sporco per me:

public class listToObservableCollection : BaseConverter, IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     HashSet<Level2> observableList = (HashSet<Level2>)value; 
     return new ObservableCollection<Level2>(observableList); 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     return (HashSet<Level2>)value; 
    } 
} 

public abstract class BaseConverter : MarkupExtension 
{ 
    public override object ProvideValue(IServiceProvider serviceProvider) 
    { 
     return this; 
    } 
} 

E metterlo sul legame della mia DataGrid2:

<!--part of my window definition--!> 
xmlns:l="clr-namespace:Recursos;assembly=Recursos" 
... 
<!--part of my resources section--!> 
<l:listToObservableCollection x:Key="listoToObservable"/> 
... 
<!--part of my datagrid definition--!> 
ItemsSource="{Binding Level2,Converter={StaticResource listoToObservable}}" 

L'unica cosa in onda è come fare un convertitore generico, ma per ora funziona bene.

+0

L'ho provato, ma sto avendo un errore nella riga seguente in xaml: ItemsSource = "{Binding Source = {StaticResource ModeloItensViewSource}, Converter = {StaticResource collectionConverter}}". L'errore è "il valore non può essere nullo. Nome del parametro: collezione". – Marlon

+0

@Marlon Ci scusiamo per il ritardo, alcuni giorni di vacanza. hai definito '' ModeloItensViewSource'' correttamente? perché è una risorsa statica? –

+0

Ho appena visto in questo modo in alcuni esempi su Internet. Ma ho rinunciato alla struttura dell'entità per questo progetto.Avevo troppi errori e problemi, ed era troppo lavoro per un piccolo progetto. Forse più tardi ci vorrà del tempo per studiarlo meglio. Ma grazie per l'attenzione comunque. – Marlon

14

Ho provato questo e il problema è che avete inizializzato la vostra collezione Level2 come Hashset<>. IEditableCollectionView.EditItem() genera questo errore durante il tentativo di aggiornare l'articolo in Hashset<>. Ho inizializzato la raccolta come List<> e funzionava correttamente.

Non sono sicuro del motivo per cui non è possibile aggiornare l'elemento in hashset, è necessario approfondirlo. Tuttavia, la modifica di Hashset<> in List<> risolverà questo errore.

Speranza che aiuta

Grazie

+6

Il motivo è perché legare un 'Datagrid' L'elemento di origine di 'Hashset' non genera una vista di insieme che implementa' IEditableCollectionView'. 'List' genererà un' ListCollectionView' che _ implementa questa interfaccia, ed è per questo che funziona. – Shoe

+0

@Jim si è corretto. leggendo lo stesso ... kudos – Nitin

+0

Questo codice viene generato automaticamente da EF, questo cambiamento influisce sulle prestazioni o su altri problemi sul mio modello relazionale. "Se no, perché EF definisce le raccolte come hashet? –

7

Si potrebbe provare questo.Fissare un gestore BeginningEdit al DataGrid e puntare a questo codice:

private void Grid_BeginningEdit(object sender, DataGridBeginningEditEventArgs e) 
    { 
     //// Have to do this in the unusual case where the border of the cell gets selected 
     //// and causes a crash 'EditItem is not allowed' 
     e.Cancel = true; 
    } 

Questo sarà solo colpire se si riesce in qualche modo a toccare fisicamente giù sul bordo della cella. OriginalSource dell'evento è un Border e penso che ciò che potrebbe accadere qui sia al posto di un TextBox, o che un altro elemento modificabile sia la fonte come previsto, questo Border non modificabile passa attraverso la modifica, il che causa un'eccezione sepolta nel ' EditItem non è permesso 'eccezione. Annullare questo RoutedEvent prima che possa passare inosservato con la sua originale non valida interrompe l'errore che si verifica nelle sue tracce.

1

è possibile impostare la proprietà IsReadOnly. forse eccezione si verifica ... provare in file XAML ..

IsReadOnly="True" 
-2

ho risolto questo mettendo il mio datagrid in modalità di sola lettura

<DataGrid 
       Name="dtgBulkInsert" 
       CanUserSortColumns="True" 
       Height="300" Visibility="Collapsed" IsReadOnly="True"> 

....

2

Qui è un Convertitore generico che ho usato

public class ObservableCollectionConverter: IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     var observableType= typeof (ObservableCollection<>).MakeGenericType(value.GetType().GetGenericArguments()); 
     return Activator.CreateInstance(observableType, value); 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     var observableType = typeof(HashSet<>).MakeGenericType(value.GetType().GetGenericArguments()); 
     return Activator.CreateInstance(observableType, value); 
    } 
} 
3

Ho anche risolto questo problema lem usando IsReadOnly="True".
È la soluzione semplice e migliore da seguire.

0

In via più breve è possibile scrivere:

DataGrid.BeginningEdit += (s, ss) => ss.Cancel = true;