1

Emblemに表示するタイプのオブジェクトのリストがありますLongListMultiSelector。まだ達成されていないものだけを示したいと思います。1 つまたは複数の項目を選択して変更できますIsAchieved = trueが、問題はそれらがすぐに消えず、UI が自動的に更新されないことです。

を使っていたので問題ないと思いましたObservableCollection<T>。その後、アイテムのプロパティが変更された場合、コレクションに通知されないことがわかりました。その結果、INotifyPropertyChangedインターフェースを実装しましたが、これも機能しません。

ここSOで、この問題を共有する次の質問(およびその他)を見つけました:

の使用法も実装しようとしましたTrulyObservableCollection<T>が、結果もありませんでした。これが私が持っているものです

XAML コントロール:

<toolkit:LongListMultiSelector Name="EmblemsList"
                               ItemsSource="{Binding Emblems}"
                               Background="Transparent"
                               LayoutMode="List"
                               ItemTemplate="{StaticResource ItemTemplate}" />

アイテムは次の方法でバインドされますEmblemsViewModel

public class EmblemsViewModel
{
    public EmblemsViewModel()
    {
        Emblems = new TrulyObservableCollection<Emblem>();
    }

    public TrulyObservableCollection<Emblem> Emblems { get; set; }
}

//Usage on the page
DataContext = new EmblemsViewModel { Emblems = DB.GetEmblems() }

クラスは次のEmblemとおりです。

public class Emblem : Achievement
{
    public int Level { get; set; }
}

public abstract class Achievement : INotifyPropertyChanged
{
    private bool _isAchieved;

    public string Description { get; set; }

    public bool IsAchieved
    {
        get { return _isAchieved; }
        set
        {
            if (_isAchieved != value)
            {
                _isAchieved = value;
                NotifyPropertyChanged("IsAchieved");
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

}

これが機能しない原因は何ですか?

アップデート:

CollectionViewSourceフィルタリングを適用するために を適用しましたが、アイテムが表示されません。

//Reference to the CollectionViewSource
_viewSource = (CollectionViewSource)Resources["EmblemsViewSource"];

//3 options in the ListBox: all, achieved & unachieved
private void FilterListBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var selectedItem = ((ListBoxItem)FilterListBox.SelectedItem).Content.ToString();

    switch (selectedItem)
    {
        case "achieved": _filter = Filter.Achieved; _viewSource.Filter += new FilterEventHandler(CollectionViewSource_Filter); break;
        case "unachieved": _filter = Filter.Unachieved; _viewSource.Filter += new FilterEventHandler(CollectionViewSource_Filter); break;
        default: _filter = Filter.All; _viewSource.Filter -= new FilterEventHandler(CollectionViewSource_Filter); break;
    } 
}

private void CollectionViewSource_Filter(object sender, FilterEventArgs e)
{
    var item = e.Item as Emblem;

    switch (_filter)
    {
        case Filter.Achieved: e.Accepted = item.IsAchieved; break;
        case Filter.Unachieved: e.Accepted = !item.IsAchieved; break;
        case Filter.All: e.Accepted = true; break;
    }
}

XAML:

<CollectionViewSource x:Key="EmblemsViewSource" Source="{Binding Emblems}" />

<toolkit:LongListMultiSelector Name="EmblemsList"
                               ItemsSource="{Binding Source={StaticResource EmblemsViewSource}}"
                               Background="Transparent"
                               LayoutMode="List"
                               ItemTemplate="{StaticResource ItemTemplate}" />
4

3 に答える 3

1

1 つの解決策は、から派生した新しいコレクションを作成しObservableCollection、新しいプロパティを追加することです。FilteredItems.

メインウィンドウ:

public partial class MainWindow : Window
{
    FilterableObservableCollection items;

    public MainWindow()
    {

        items = new FilterableObservableCollection()
        {
            new ListViewItem() { Name = "Hallo", IsArchived = false },
            new ListViewItem() { Name = "world", IsArchived = true },
            new ListViewItem() { Name = "!!!", IsArchived = false }
        };

        InitializeComponent();
    }

    public FilterableObservableCollection MyItems
    {
        get { return items; }
    }

    private void CheckBox_Checked(object sender, RoutedEventArgs e)
    {
        items.NotArchivedOnlyFilterEnabled = (sender as CheckBox).IsChecked.Value;
    }

    private void CheckBox_Unchecked(object sender, RoutedEventArgs e)
    {
        items.NotArchivedOnlyFilterEnabled = (sender as CheckBox).IsChecked.Value;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        items.Add(new ListViewItem() { Name = "Item" + (items.Count + 1), IsArchived = items.Count % 2 == 0 });
    }
}

カスタム監視可能なコレクション:

public class FilterableObservableCollection : ObservableCollection<ListViewItem>
{
    private bool notArchivedOnlyFilterEnabled;

    public IEnumerable<ListViewItem> FilteredItems
    {
        get
        {
            if (notArchivedOnlyFilterEnabled)
            {
                return this.Where(x => x.IsArchived == false);

            }
            else
            {
                return this;
            }
        }
    }

    public bool NotArchivedOnlyFilterEnabled
    {
        get { return notArchivedOnlyFilterEnabled; }
        set
        {
            notArchivedOnlyFilterEnabled = value;
            OnPropertyChanged(new PropertyChangedEventArgs("FilteredItems"));
        }
    }
}

データ項目

public class ListViewItem
{
    public string Name { get; set; }

    public bool IsArchived { get; set; }
}

XAML :

<Window x:Class="ObservableCollectionDemo1.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"
        DataContext="{Binding RelativeSource={RelativeSource Self}}"
        xmlns:c="clr-namespace:ObservableCollectionDemo1">
    <Grid>
        <ListView HorizontalAlignment="Left" Height="142" Margin="81,47,0,0" VerticalAlignment="Top" Width="302" x:Name="listView" DataContext="{Binding MyItems}" ItemsSource="{Binding FilteredItems}">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"  Width="100"/>
                    <GridViewColumn Header="Is Archived" DisplayMemberBinding="{Binding IsArchived}" Width="100"/>
                </GridView>
            </ListView.View>
        </ListView>
        <CheckBox Content="Is Not Archived" HorizontalAlignment="Left" Margin="278,194,0,0" VerticalAlignment="Top" Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked"/>
        <Button Content="New Item" HorizontalAlignment="Left" Margin="278,214,0,0" VerticalAlignment="Top" Width="105" Click="Button_Click"/>

    </Grid>
</Window>
于 2014-12-16T07:59:46.883 に答える