2

WPF が期待どおりに動作しないという、非常に奇妙な動作が見られます。次のコードで問題を解決できました。

XAML:

<Window x:Class="WpfApplication3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">

    <TabControl x:Name="tabControl">
        <TabControl.ContentTemplate>
            <DataTemplate DataType="{x:Type List}">
                <UserControl>

                    <UserControl.Resources>
                        <CollectionViewSource x:Key="filteredValues" Source="{Binding}" Filter="CollectionViewSource_Filter" />
                    </UserControl.Resources>

                    <ListBox ItemsSource="{Binding Source={StaticResource filteredValues}}" />

                </UserControl>
            </DataTemplate>
        </TabControl.ContentTemplate>
    </TabControl>

</Window>

分離コード:

using System.Collections.Generic;
using System.Windows;
using System.Windows.Data;

namespace WpfApplication3
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            this.tabControl.ItemsSource = new List<List<string>>()
            {
                new List<string>() { "a", "b", "c"},
            };
        }

        private void CollectionViewSource_Filter(object sender, FilterEventArgs e)
        {
            string item = (string)e.Item;
            e.Accepted = item.StartsWith("b");
        }
    }
}

このコードは、「b」という 1 つの項目を持つ withTabControlが 1 つのタブになることを期待しています。ListBoxしかし、代わりに、ListBox3 つの文字列すべてで a が得られます。内部にブレークポイントを設定するCollectionViewSource_Filterと、フィルターが実行されないことが示されます。

何が起きてる?フィルタが機能しないのはなぜですか?

CollectionViewSourceのリソースであることと関係があるのではないかと考えていましたDataTemplateListBoxちゃんと火がついたイベント。UserControlが の一部でない場合DataTemplate、Filter イベントは正常に機能します。

編集:

たとえば、次の例は期待どおりに機能し、List は期待どおりにフィルタリングされます。

XAML:

<Window x:Class="WpfApplication3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">

    <UserControl>

        <UserControl.Resources>
            <CollectionViewSource x:Key="filteredValues" Source="{Binding}" Filter="CollectionViewSource_Filter" />
        </UserControl.Resources>

        <ListBox ItemsSource="{Binding Source={StaticResource filteredValues}}" />

    </UserControl>

</Window>

コードビハインド:

using System.Collections.Generic;
using System.Windows;
using System.Windows.Data;

namespace WpfApplication3
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            this.DataContext = new List<string>() { "a", "b", "c" };
        }

        private void CollectionViewSource_Filter(object sender, FilterEventArgs e)
        {
            string item = (string)e.Item;
            e.Accepted = item.StartsWith("b");
        }
    }
}
4

3 に答える 3

3

なぜうまくいかないのかはわかりませんが、現時点では Microsoft のバグだと思います。近日中に Connect レポートを提出する予定です。

バグを回避するために、次のことを行いました。CollectionViewSource次のようなサブクラスを作成しました。

using System.Windows.Data;

namespace WpfApplication3
{
    internal class CustomFilteredCollectionViewSource : CollectionViewSource
    {
        public CustomFilteredCollectionViewSource()
            : base()
        {
            this.Filter += CustomFilter;
        }

        private void CustomFilter(object sender, FilterEventArgs args)
        {
            string item = (string)args.Item;
            args.Accepted = item.StartsWith("b");
        }
    }
}

その後交換しました

<CollectionViewSource x:Key="filteredValues" Source="{Binding}" Filter="CollectionViewSource_Filter" />

<local:CustomFilteredCollectionViewSource x:Key="filteredValues" Source="{Binding}" />

そして今では完全に機能します。

于 2010-10-21T18:27:35.293 に答える
1

常に使用されるCollectionViewSourceのプロパティであるかのように、フィルターを使用しています。

そうではありません。それはイベントです。「このCollectionViewSourceをフィルタリングすると、このイベントが呼び出されます」と表示されます。フィルタリングのリクエストには応答しますが、それらのリクエスト自体はトリガーされません。

CollectionViewSourceについてはあまりわかりませんが、このイベントをトリガーするには、フィルタリングを許可したグリッドのように、フィルタリングコントロールにバインドする必要があると思います。

于 2010-10-21T17:00:11.617 に答える