Frage

Ich habe eine MainWindow.xaml-Datei:

<Window.Resources>

  <CollectionViewSource x:Key="cvs" 
    Source="{Binding Source={StaticResource ResourceKey=DetailsCollection}}" />

  <CollectionViewSource x:Key="DetailScopes">
    <CollectionViewSource.Source>
      <ObjectDataProvider 
        MethodName="GetValues" 
        ObjectType="{x:Type system:Enum}">
        <ObjectDataProvider.MethodParameters>
          <x:Type TypeName="entities:DetailScope" />
        </ObjectDataProvider.MethodParameters>
      </ObjectDataProvider>
    </CollectionViewSource.Source>
  </CollectionViewSource>

  <DataTemplate x:Key="AccountDetail"
    DataType="{x:Type entities:AccountDetail}">
    <DockPanel>
      <ComboBox 
        DockPanel.Dock="Left" 
        ItemsSource="{Binding Source={StaticResource ResourceKey=DetailScopes}}" 
        SelectedItem="{Binding Path=Scope}">
        <ComboBox.ItemTemplate>
          <DataTemplate>
            <TextBlock 
              Text="{Binding Converter={StaticResource DetailScopeConverter}}" />
          </DataTemplate>
        </ComboBox.ItemTemplate>
      </ComboBox>
      <TextBox Text="{Binding Path=Value}" />
    </DockPanel>
  </DataTemplate>

</Window.Resources>

...

<ListBox 
  ItemTemplate="{StaticResource ResourceKey=AccountDetail}" 
  ItemsSource="{Binding Source={StaticResource ResourceKey=cvs}}" />

und seine Code-Behind-Klasse, wo ich die Filter für Detail definiert Tive:

public class MainWindow
{
    public MainWindow()
    {
        CollectionViewSource detailScopes;

        InitializeComponent();

        // Attach filter to the collection view source
        detailScopes = this.Resources["DetailScopes"] as CollectionViewSource;
        detailScopes.Filter += new FilterEventHandler(DetailScopesFilter);

        private void DetailScopesFilter(object sender, FilterEventArgs e)
        {
            DetailScope scope;

            scope = (DetailScope)e.Item;
            if (scope == DetailScope.Private ||
                scope == DetailScope.Business)
            {
                e.Accepted = true;
            }
            else
            {
                e.Accepted = false;
            }
        }
    }
}

Als nächstes gibt es die AccountDetail Klasse:

public class AccountDetail
{
  public string Value
  {
    get { return this.value; }
    set { this.value = value; }
  }
  public DetailScope Scope
  {
    get { return scope; }
    set { scope = value; }
  }

  private string value;
  private DetailScope scope;
}

Schließlich ist ein Enum:

public enum DetailScope
{
  Private, 
  Business, 
  Other
}

Wenn ich meinen Code ausführen, bekomme ich ein Listenfeld mit einem Bündel von Kontodaten bevölkert, von denen jeder seine eigene Combo-Box mit einem ausgewählten Bereich und ein Textfeld mit dem entsprechenden Wert. Das Problem ist, dass alle die ausgewählten Werte in den Kombinationsfeldern den Umfang Satz für das zuletzt eingegebenen Detail und Ändern von einem der Combo-Box Werte aktualisieren alle von ihnen entsprechen, als ob sie alle auf das gleiche Konto Detail gebunden sind.

Wenn ich die ObjectDataProvider von dem CollectionViewSource DetailScopes herausnehmen und bindet es direkt an den ItemsSource des Kombinationsfelds in der DataTemplate AccountDetail, ist das Problem verschwunden. Aber ich brauche es in der CollectionViewSource weil ich etwas zu filtern sie beantrage, und ich kann das Filtern auf ObjectDataProvider nicht anwendbar.

Könnte jemand bitte erklären, warum dies geschieht und wie soll ich eigentlich zu verbinden CollectionViewSource und ObjectDataProvider? Vielen Dank.

War es hilfreich?

Lösung

.

Das Problem mit Ihrem Code ist, dass jede ComboBox ist die gleiche Instanz von Collection mit ; das bedeutet, ist die Ressource, mit der Taste „DetailScopes“ geteilt durch all ComboBox-, so, wenn Sie einen Wert von einem bestimmten ComboBox auswählen, wählt es automatisch den gleichen Wert in allen ComboBox. Es ist, weil die zugrunde liegende Sammlung, die gemeinsam genutzt wird, den Überblick über das ausgewählte Element hält, und da es ändert sich auf die Auswahl von einem ComboBox, die Collection meldet die Änderung auf alle ComboBox .

So ist die Lösung sehr einfach. Alles was Sie brauchen DetailScopes Ressource unsharable .

machen

Hier ist das Update:

<!-- Please note this x:Shared="False" just after x:Key="DetailsScopes" --->

<CollectionViewSource x:Key="DetailScopes"  x:Shared="False"> 
    <CollectionViewSource.Source>
      <ObjectDataProvider 
        MethodName="GetValues" 
        ObjectType="{x:Type system:Enum}">
        <ObjectDataProvider.MethodParameters>
          <x:Type TypeName="entities:DetailScope" />
        </ObjectDataProvider.MethodParameters>
      </ObjectDataProvider>
    </CollectionViewSource.Source>
  </CollectionViewSource>

Hope es löst Ihr Problem!

Allerdings ist diese Lösung wird ein anderes Problem verursachen. Lassen Sie mich etwas von MSDN zitieren, so dass Sie verstehen, was x:. Geteilt tut

  

x: Geteilt Attribut

     

Bei der Einstellung falsch ist, ändert WPF Ressource-Abruf   Verhalten, so dass Anfragen für die   zugeschrieben Ressource Erstellen Sie eine neue   Beispiel für jede Anforderung statt   teilen die gleiche Instanz für alle   Anfragen.

Da x: Geteilt wird eine neue Instanz (eine neue Kopie) der Ressource erstellen, wenn Sie den Zugriff versuchen es, das bedeutet, wird die Filter-Handler-Methode angebracht nur auf die Instanz, die Sie im bekommen Code-behind, nicht alle Instanzen.

Also, um Ihre Handler richtig funktioniert, müssen Sie den Handler von XAML selbst, so befestigen:

<!-- Now please note Filter="DetailsScopesFilter" --->

<CollectionViewSource x:Key="DetailScopes"  x:Shared="False"  Filter="DetailScopesFilter"> 
    <CollectionViewSource.Source>
      <ObjectDataProvider 
        MethodName="GetValues" 
        ObjectType="{x:Type system:Enum}">
        <ObjectDataProvider.MethodParameters>
          <x:Type TypeName="entities:DetailScope" />
        </ObjectDataProvider.MethodParameters>
      </ObjectDataProvider>
    </CollectionViewSource.Source>
  </CollectionViewSource>

Hope es löst alle Probleme. Lassen Sie mich wissen, wenn Sie noch irgendwelche Gesicht: -).

Ach übrigens, der folgende Code-Behind wird nicht mehr benötigt. Also bitte nehmen Sie es.

    // Attach filter to the collection view source
    detailScopes = this.Resources["DetailScopes"] as CollectionViewSource;
    detailScopes.Filter += new FilterEventHandler(DetailScopesFilter);

.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top