Domanda

Ho un file MainWindow.xaml:

<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}}" />

e la sua classe code-behind, dove ho definito il filtro per il dettaglio Scopes:

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;
            }
        }
    }
}

Avanti, c'è la classe AccountDetail:

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;
}

Infine, un enum:

public enum DetailScope
{
  Private, 
  Business, 
  Other
}

Quando eseguo il mio codice, ottengo una casella di riepilogo popolato con un mucchio di dettagli del conto, ciascuno con la propria casella combinata con un campo di applicazione selezionata e una casella di testo con il valore appropriato. Il problema è che tutti i valori selezionati nelle caselle combinate corrispondono il set ambito per il dettaglio è entrato e cambiare qualsiasi valore casella combinata aggiorna tutti loro, come se fossero tutti legati allo stesso account dettagli.

Quando prendo la ObjectDataProvider dalle DetailScopes CollectionViewSource e si legano direttamente al ItemsSource della casella combinata nel DataTemplate AccountDetail, il problema è andato. Tuttavia, ho bisogno all'interno del CollectionViewSource perché Mi candido qualche filtro ad esso e non posso applicare il filtro a ObjectDataProvider.

Qualcuno potrebbe spiegare perché questo sta accadendo e come sono in realtà dovrebbe CollectionViewSource connessione e ObjectDataProvider? Grazie.

È stato utile?

Soluzione

.

Il problema con il vostro codice è che ogni ComboBox è utilizzando la stessa istanza di CollectionViewSource ; Ciò significa che, con la risorsa chiave "DetailScopes" è condiviso da tutti ComboBox, quindi, quando si seleziona un valore da un particolare ComboBox, si seleziona automaticamente lo stesso valore in tutto ComboBox. E 'perché la raccolta di fondo che è condiviso, tiene traccia della voce selezionata, e dal momento che cambia sulla selezione da una casella combinata, la Notifica CollectionViewSource la modifica a tutte ComboBox .

Quindi la soluzione è molto semplice. Tutto quello che devi fare risorsa DetailScopes non condivisibile .

Ecco la correzione:

<!-- 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>

La speranza si risolve il problema!

Tuttavia, questa soluzione causerà un altro problema. Permettetemi di citare qualcosa da MSDN, in modo che capirete cosa x:. Non condivisa

  

x: Shared attributo

     

Se impostato su False, modifica WPF risorse recupero   comportamento in modo che le richieste per la   risorsa attribuito creare una nuova   istanza per ogni richiesta al posto di   condividendo la stessa istanza per tutti   richieste.

Dato che x: provoca condivisa per creare una nuova istanza (una nuova copia) della risorsa ogni volta che si tenta di accedervi, che i mezzi, il metodo del gestore Filtro riguarda solo l'istanza che si ottiene nel code-behind, non tutte le istanze.

Quindi, al fine di lavorare il vostro gestore correttamente, è necessario collegare il Handler da XAML stesso, in questo modo:

<!-- 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>

La speranza risolve tutti i vostri problemi. Fatemi sapere se avete ancora affrontare qualsiasi: -).

Oh, a proposito, il seguente code-behind non è più necessaria. Quindi, per favore rimuoverlo.

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

.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top