我有一个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 帐户尾尾,问题已经消失。但是,我确实需要它 CollectionViewSource 因为我正在对其进行一些过滤,所以我无法将过滤应用于 ObjectDataProvider.

有人可以解释为什么会发生这种情况,以及我实际上应该如何联系 CollectionViewSourceObjectDataProvider?谢谢你。

有帮助吗?

解决方案

.

您的代码问题是 每个组合都使用CollectionViewSource的相同实例;这意味着,具有关键“详细信息”的资源是 由所有人共享 Combobox,因此,每当您从特定的ComboBox中选择一个值时,它都会在所有ComboBox中自动选择相同的值。 这是因为共享的基础集合可以跟踪所选项目,并且由于它从一个ComboBox选择时进行了更改,因此CollectionViewSource通知了所有ComboBox的更改.

因此解决方案非常简单。您需要进行详细信息资源 不可出现.

这是解决方案:

<!-- 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:共享的作用。

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