应用程序在WPF中运行时保持复选框状态

时间:2017-11-14 11:48:42

标签: c# wpf checkbox mvvm

我在MVVM,WPF工作,我有一个弹出窗口;在这个弹出窗口中是一个列表框,在列表框中我有一个复选框。问题是:如果我从列表框中取消选中一个项目并单击“外部”,弹出窗口将消失;如果我再次点击,则复选框将重置为其初始值(所有项目都将被选中)。

那么,如何在应用程序运行时保持弹出窗口的状态并停止重置?我可以通过XAML做到这一点吗?

这是代码:

public class CheckedListItem<T> : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private bool isChecked = false;
    private T item;

    public CheckedListItem()
    { }

    public CheckedListItem(T item, bool isChecked)
    {
        this.item = item;
        this.isChecked = isChecked;
    }

    public T Item
    {
        get { return item; }
        set
        {
            item = value;
            if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Item"));
        }
    }

    public bool IsChecked
    {
        get { return isChecked; }
        set
        {
            isChecked = value;
            if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("IsChecked"));
        }
    }
}

viewModel:

 private void OnApplyFiltersCommandRaised(object obj)
    {
         if (FilterElement.Contains("ClassView"))
        {
            switch (FilterElement)
            {
                case "buttonClassViewClassFilter":
                    FilteredClassViewItems.Clear();
                    FilteredFieldViewItems.Clear();
                    foreach (var filterItem in FilterItems)
                    {
                        if (filterItem.IsChecked == true)
                        {
                            FilteredClassViewItems.Add(classViewItems.First(c => c.ClassName == filterItem.Item));
                            FilteredFieldViewItems.Add(fieldViewItems.First(c => c.ClassName == filterItem.Item));

                        }
                    }

                    break;
...

public ObservableCollection<CheckedListItem<string>> FilterItems
    {
        get
        {
            return filterItems;
        }

        set
        {
            filterItems = value;
            SetPropertyChanged("FilterItems");

        }
    }

XAML部分:

              <ListBox x:Name="listBoxPopupContent" 
                             Height="250" 
                             ItemsSource="{Binding FilterItems}" 
                             BorderThickness="0" 
                             ScrollViewer.VerticalScrollBarVisibility="Auto">
                        <ListBox.Resources>
                            <Style TargetType="{x:Type ListBoxItem}">
                                <Setter Property="FontSize" Value="8" />
                                <Setter Property="IsSelected" Value="{Binding IsChecked, Mode=TwoWay}" />
                            </Style>

                        </ListBox.Resources>
                        <ListBox.ItemTemplate>
                            <DataTemplate>
                                <CheckBox IsChecked="{Binding IsChecked}" 
                                          Content="{Binding Item}" 
                                          Command="{Binding DataContext.ApplyFiltersCommand, 
                                                RelativeSource={RelativeSource FindAncestor, 
                                                AncestorType={x:Type ListBox}}}"
                                          CommandParameter="{Binding IsChecked, 
                                                RelativeSource={RelativeSource Self}, 
                                                Mode=OneWay}"/>
                            </DataTemplate>
                        </ListBox.ItemTemplate>
                    </ListBox>

提前致谢!

1 个答案:

答案 0 :(得分:0)

如果要保持状态,可以创建一个包含列表框的新视图。然后你的弹出窗口将是

<Popup>
   <views:MyListBoxview>
</Popup>

其中views是wpf可以找到MyListBoxview的路径。

这是一个如何做MyListBoxView的例子。首先,为项目添加一个新的usercontrol。然后你创建:

<ListBox ItemSource = {Binding MyCollectionOfItem}>
    <ListBox.ItemTemplate>
        <DataTemplate>
           <CheckBox IsChecked = {Binding IsItemChecked} Content = {Binding Name}/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

您需要为此视图分配一个视图模型,该视图模型当然会实现INotifyPropertyChanged并且将在其中定义这些类(此类也将实现INotifyPropertyChanged)

public class MyItem : INotifyPropertyChanged
{
    public void SetPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    public event PropertyChangedEventHandler PropertyChanged;

    private bool isItemChecked = false;
    public bool IsItemChecked
    {
        get { return isItemChecked; }
        set
        {
            isItemChecked = value;
            SetPropertyChanged("IsItemChecked");
        }
    }

    private string name ;
    public string Name
    {
        get { return Name; }
        set
        {
            name = value;
            SetPropertyChanged("Name");
        }
    }
}

最后,代表弹出窗口状态的viewmodel将包含在此属性

private ObservableCollection<MyItem> myCollectionOfItem = new ObservableCollection<MyItem>();
public ObservableCollection<MyItem> MyCollectionOfItem
{
    get { return myCollectionOfItem; }
    set
    {
        myCollectionOfItem = value;
        SetPropertyChanged("MyCollectionOfItem");
    }
}

我通常会处理这种问题,正确地建模我需要绑定到WPF中的控件的对象