【问题标题】:Maintain checkbox state while the app is running in WPF在 WPF 中运行应用程序时保持复选框状态
【发布时间】:2018-04-27 08:37:50
【问题描述】:

我正在使用 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"));
        }
    }
}

视图模型:

 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>

提前致谢!

【问题讨论】:

  • 您应该考虑维护作为弹出窗口的 DataContext 的数据状态,而不是 UI 控件的状态。你真的在使用 MVVM 模式吗?
  • @Crowcoder 复选框状态是通过我的viewModel存储的,但是我不知道如何正确维护日期的状态
  • @Nica 这应该可以。关于您的问题(重新打开所有复选框都已选中),您应该观察 FilterItems 与其余代码的交互。如果你不搞乱它,属性 IsChecked 不能单独改变它的状态
  • @DanieleSartori 好的..我在方法中搞砸了(ApplyFilter)..我检查 isChecked 是否为真我相应地填写列..我试图在代码中添加这个: .. 复选框中的所有项目都未选中,但状态仍然没有保持.. 有什么想法吗?
  • @Nica 抱歉,我不明白。你解决了你的问题吗?因为问题已得到解答,并且我解释的方法是保持复选框状态的一种方法。如果您有其他问题,可以打开一个新问题。编辑:你在哪里添加了那个二传手?

标签: c# wpf checkbox mvvm


【解决方案1】:

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

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

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

这是一个如何执行 MyListBoxView 的示例。首先,在您的项目中添加一个新的用户控件。然后你创建:

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

最后,代表弹出窗口状态的视图模型将包含在此属性中

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

我通常会正确处理此类问题,我需要在 WPF 中绑定到我的控件的对象

【讨论】:

  • 我通过 IsChecked 属性存储了我的复选框的状态。我不知道如何使用这个 ?我应该在 中包含我的 .. 吗?
  • 复选框状态通过我的viewModel存储..但我不清楚如何构建我的sintax
  • hmm.. 这很奇怪.. 之前完成了所有这些步骤(使用 SetPropertyChanged("MyCollectionOfItem") 的步骤除外).. 但是如果我关闭并重新打开复选框,复选框确实会保持状态复选框,所有项目都被选中..
  • 当然,您必须将视图模型的实例存储在某个地方,然后每次打开弹出窗口时,您都会将其重新分配为 MyListBoxview 的数据上下文。还记得设置 private bool isItemChecked = false;默认情况下取消选中所有复选框
  • 我的代码与您的 MyListBoxView 示例类似...我错过了什么吗?
猜你喜欢
  • 2012-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-25
  • 2016-06-19
  • 1970-01-01
相关资源
最近更新 更多