2011-09-13 3 views
0

J'ai un petit puzzle que je suis en train de résoudre et je ne suis pas sûr de savoir comment s'y prendre ...liaisons classe désérialisation et WPF

application WPF basée sur l'approche MVVM ...

Je une classe qui hérite de SubstituionDataSet DataSet et définit une collection supplémentaire:

namespace Lib 
{ 
    public class SubstitutionDataSet : DataSet 
    { 
     public SubstitutionDataSet() 
     { 
      TableNames = new ObservableCollection<SubstitutionDataTable>(); 

      Tables.CollectionChanging += DataTablesCollectionChanging; 
     } 

     public ObservableCollection<SubstitutionDataTable> TableNames { get; set; } 

     private void DataTablesCollectionChanging(object sender, CollectionChangeEventArgs e) 
     { 
      var actionTable = (DataTable) e.Element; 

      if (e.Action == CollectionChangeAction.Add) 
      { 
       actionTable.Columns.CollectionChanged += DataColumnCollectionChanged; 
       TableNames.Add(new SubstitutionDataTable { Name = actionTable.TableName }); 
      } 
      else if (e.Action == CollectionChangeAction.Remove) 
      { 
       actionTable.Columns.CollectionChanged -= DataColumnCollectionChanged; 
       TableNames.Remove(TableNames.First(tn => tn.Name == actionTable.TableName)); 
      } 
     } 

     private void DataColumnCollectionChanged(object sender, CollectionChangeEventArgs e) 
     { 
      var actionColumn = (DataColumn) e.Element; 
      var hostTable = (DataTable) actionColumn.Table; 
      var hostSubsitutionTable = TableNames.First(tn => tn.Name == hostTable.TableName); 

      if (e.Action == CollectionChangeAction.Add) 
      { 
       hostSubsitutionTable.ColumnNames.Add(actionColumn.ColumnName); 
      } 
      else if (e.Action == CollectionChangeAction.Remove) 
      { 
       hostSubsitutionTable.ColumnNames.Remove(hostSubsitutionTable.ColumnNames.First(cn => cn == actionColumn.ColumnName)); 
      } 
     } 
    } 
} 

Avec le SubstitutionDataTable défini comme ci-dessous:

namespace Lib 
{ 
    public sealed class SubstitutionDataTable: INotifyPropertyChanged 
    { 
     private string _name; 

     /// <summary> 
     /// The <see cref="Name" /> property's name. 
     /// </summary> 
     private const string NamePropertyName = "Name"; 

     public SubstitutionDataTable() 
     { 
      ColumnNames = new ObservableCollection<string>(); 
     } 

     /// <summary> 
     /// Gets the Name property. 
     /// Changes to that property's value raise the PropertyChanged event. 
     /// </summary> 
     public string Name 
     { 
      get 
      { 
       return _name; 
      } 

      set 
      { 
       if (_name == value) 
       { 
        return; 
       } 

       _name = value; 

       RaisePropertyChanged(NamePropertyName); 
      } 
     } 

     public ObservableCollection<string> ColumnNames { get; set; } 


     #region Implementation of INotifyPropertyChanged 

     /// <summary> 
     /// A property has changed - update bindings 
     /// </summary> 
     [field: NonSerialized] 
     public event PropertyChangedEventHandler PropertyChanged; 

     private void RaisePropertyChanged(string propertyName) 
     { 
      var handler = PropertyChanged; 
      if (handler != null) 
      { 
       handler(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 

     #endregion 
    } 
} 

... Maintenant, c'est le cœur du puzzle ...

Les classes ci-dessus sont utilisées pour définir un nouveau DataTable dans un DataSet et ajouter des colonnes et des lignes et run-time. J'ai une autre classe qui permet la configuration d'un processus d'obfuscation, une partie de la configuration permet la sélection d'un DataTable et DataColumn à partir du SubstituionDataSet défini ci-dessus. J'ai la configuration de travail et peut configurer un certain nombre d'obfuscations, puis sérialiser la configuration sur le disque. Lorsque je désérialise, je trouve que les liaisons sur l'interface graphique n'affiche pas les sélections DataTable et DataColumn correctes, le DataTable affiche simplement le nom d'objet qualifié complet.

Je suis actuellement en train d'essayer de faire fonctionner la liaison DataTable - Je sais que j'ai besoin de retravailler la liaison DataColumn.

L'interface graphique (usercontrol) est définie comme suit:

<UserControl xmlns:igEditors="http://infragistics.com/Editors" x:Class="SubstitutionOptions" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" 
      d:DesignHeight="421" d:DesignWidth="395"> 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="23" /> 
      <RowDefinition Height="23" /> 
      <RowDefinition Height="*" /> 
     </Grid.RowDefinitions> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="150" /> 
      <ColumnDefinition Width="20" /> 
      <ColumnDefinition Width="*" /> 
     </Grid.ColumnDefinitions> 

     <TextBlock Grid.Row="0" 
        Grid.Column="0" 
        Text="Dataset" /> 
     <igEditors:XamComboEditor Grid.Row="0" 
            Grid.Column="2" 
            Name="tablesComboBox" 
            NullText="select a dataset..." 
            ItemsSource="{Binding DataContext.Project.SubstitutionDataSet.TableNames, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" 
            DisplayMemberPath="Name" 
            SelectedItem="{Binding DataContext.SelectedFieldSubstitutionDataTable, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"/> 

     <TextBlock Grid.Row="1" 
        Grid.Column="0" 
        Text="Column" /> 
     <igEditors:XamComboEditor Grid.Row="1" 
            Grid.Column="2" 
            NullText="select a column..." 
            ItemsSource="{Binding DataContext.SelectedFieldSubstitutionDataTable.ColumnNames, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" 
            SelectedItem="{Binding DataColumn, Mode=TwoWay}"/> 
    </Grid> 
</UserControl> 

J'espère avoir suffisamment expliqué le problème. Quelqu'un at-il des idées sur la façon dont je peux le faire fonctionner en utilisant la conception actuelle ou la refonte de l'approche pour réaliser ce dont j'ai besoin?

+0

OK, pas de réponses ... J'ai fait en partie travaillé autour du problème. J'ai remplacé l'opérateur égal sur SubstitutionDataTable. Quand les objets sont désérialisés, j'obtiens les liaisons combobox pour travailler, presque ... Je trouve que le premier champ que je regarde a lié correctement mais chaque fois que je clique sur un autre champ il contient la reliure présentée dans le premier ... Hmmmm, des idées? – Drammy

Répondre

0

OK, je pense ai craqué maintenant, que personne ne semble intéressé :-)

Je posterai la réponse pour la postérité si ...

J'ai changé les fixations pour le Comboboxes comme alors ...

<TextBlock Grid.Row="0" 
      Grid.Column="0" 
      Text="Dataset" /> 
<igEditors:XamComboEditor Grid.Row="0" 
          Grid.Column="2" 
          NullText="select a dataset..." 
          ItemsSource="{Binding DataContext.VDOProject.SubstitutionDataSet.TableNames, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" 
          DisplayMemberPath="Name" 
          Text="{Binding DataTable, Mode=TwoWay}" 
          SelectedItem="{Binding DataContext.SelectedFieldSubstitutionDataTable, Mode=OneWayToSource, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"/> 

<TextBlock Grid.Row="1" 
      Grid.Column="0" 
      Text="Column" /> 
<igEditors:XamComboEditor Grid.Row="1" 
          Grid.Column="2" 
          NullText="select a column..." 
          ItemsSource="{Binding DataContext.SelectedFieldSubstitutionDataTable.ColumnNames, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" 
          Text="{Binding DataColumn, Mode=TwoWay}" />