質問

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

そして、そのコードビハインドクラスでは、詳細スコープのフィルターを定義しました。

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

次に、があります 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;
}

最後に、列挙:

public enum DetailScope
{
  Private, 
  Business, 
  Other
}

コードを実行すると、アカウントの詳細が多数入力されたリストボックスがあります。それぞれに、選択したスコープと適切な値のテキストボックスを備えた独自のコンボボックスがあります。問題は、コンボボックス内のすべての選択された値が、最後に入力された詳細のスコープセットと一致し、それらがすべて同じアカウントの詳細にバインドされているかのように、それらすべてを更新するコンボボックス値を変更することです。

私が取り出すとき ObjectDataProvider から CollectionViewSource 詳細なコープとそれをコンボボックスに直接バインドします ItemsSource の中に DataTemplate accountdetail、問題はなくなりました。ただし、内部で必要です CollectionViewSource 私はそれにいくつかのフィルタリングを適用していて、フィルタリングを適用できないからです ObjectDataProvider.

なぜこれが起こっているのか、そして私が実際に接続することになっているのはなぜかを説明してもらえますか CollectionViewSourceObjectDataProvider?ありがとうございました。

役に立ちましたか?

解決

.

コードの問題はそれです すべてのコンボボックスは、CollectionViewSourceの同じインスタンスを使用しています;つまり、キー「DetailingCopes」を備えたリソースは すべてが共有します コンボボックスは、特定のコンボボックスから1つの値を選択するたびに、すべてのコンボボックスで同じ値を自動的に選択します。 それは、共有されている基礎となるコレクションが選択したアイテムを追跡し、1つのコンボボックスから選択すると変更されるため、CollectionViewSourceはすべてのコンボボックスの変更に通知するためです.

そのため、ソリューションは非常に簡単です。詳細コープリソースを作成するために必要なすべて 恥ずかしくない.

これが修正です:

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

それがあなたの問題を解決することを願っています!

ただし、このソリューションは別の問題を引き起こします。 MSDNから何かを引用させてください。そうすれば、X:Sharedが何をするかを理解できます。

X:共有属性

falseに設定した場合、WPFリソース - レトリエバルの動作を変更して、属性リソースのリクエストが 各リクエストの新しいインスタンスを作成します すべてのリクエストに対して同じインスタンスを共有する代わりに。

x:共有原因は、アクセスしようとするたびにリソースの新しいインスタンス(新しいコピー)を作成するため、フィルターハンドラーメソッドは、すべてではなく、コードビハインドで取得するインスタンスにのみ添付されます。インスタンス。

したがって、ハンドラーを適切に動作させるには、XAML自体からハンドラーを添付する必要があります。

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

それがあなたのすべての問題を解決することを願っています。まだ直面している場合は教えてください。:-)

ちなみに、次のコードビヒンドはもう必要ありません。削除してください。

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

.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top