sdileep1 Ответов: 1

Wpf listview стиль заголовка флажок threestate


Привет,
Я застрял на том, чтобы сделать флажок threestate.
Я создал образец, как показано ниже. Когда дочерние элементы выбранного родительского флажка должна показать проверка/снимите/Indetermine
Может ли кто-нибудь помочь в приведенном ниже коде, чтобы заставить его работать threestate of checkbox?

Заранее спасибо.

Что я уже пробовал:

Окна.язык XAML:
<Window x:Class="SampleLV.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:SampleLV"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <ListView x:Name="listview">

            <!-- View -->
            <ListView.View>
                <GridView>
                    <GridViewColumn Width="50">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate DataType="cls:Item">
                                <CheckBox IsChecked="{Binding Selected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Checked="CheckBox_Checked" />
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>

                    <GridViewColumn Width="300" Header="Name" DisplayMemberBinding="{Binding Name, UpdateSourceTrigger=PropertyChanged}"></GridViewColumn>

                    <GridViewColumn Width="100" Header="Type" DisplayMemberBinding="{Binding Type}"></GridViewColumn>
                </GridView>
            </ListView.View>

            <!-- Group style -->
            <ListView.GroupStyle>
                <GroupStyle>
                    <GroupStyle.ContainerStyle>
                        <Style TargetType="{x:Type GroupItem}">
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate>
                                        <Expander x:Name="exp" IsExpanded="True">
                                            <Expander.Header>
                                                <StackPanel Orientation="Horizontal">
                                                    <CheckBox Checked="OnGroupChecked" IsThreeState="True" IsChecked="{Binding DataContext.IsSelected, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Unchecked="OnGroupUnchecked" 
                                                              Visibility="{Binding }"></CheckBox>
                                                    <TextBlock Text="{Binding Name}" />
                                                    <TextBlock Text="{Binding ItemCount, StringFormat='- {0} item(s)'}" />
                                                </StackPanel>
                                            </Expander.Header>
                                            <ItemsPresenter />
                                        </Expander>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </GroupStyle.ContainerStyle>
                </GroupStyle>
            </ListView.GroupStyle>
        </ListView>
    </Grid>
</Window>


Окна.язык XAML.в CS:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace SampleLV
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// 
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            var lst = new List<item>();
            lst.Add(new Item { Name = "A", Type = "1" });
            lst.Add(new Item { Name = "B", Type = "1" });
            lst.Add(new Item { Name = "C", Type = "1" });
            lst.Add(new Item { Name = "A", Type = "2" });
            lst.Add(new Item { Name = "B", Type = "2" });
            lst.Add(new Item { Name = "C", Type = "2" });

            listview.ItemsSource = lst;

            var view = CollectionViewSource.GetDefaultView(lst);
            view.GroupDescriptions.Add(new PropertyGroupDescription("Type"));
        }

        private void OnGroupChecked(object sender, RoutedEventArgs e)
        {
            this.HandleGroupCheck((CheckBox)sender, true);
        }

        private void HandleGroupCheck(CheckBox sender, bool check)
        {
            var group = (CollectionViewGroup)sender.DataContext;
            this.HandleGroupCheckRecursive(group, check);
        }

        private void HandleGroupCheckRecursive(CollectionViewGroup group, bool check)
        {
            foreach (var itemOrGroup in group.Items)
            {
                if (itemOrGroup is CollectionViewGroup)
                {
                    // Found a nested group - recursively run this method again
                    this.HandleGroupCheckRecursive(itemOrGroup as CollectionViewGroup, check);
                }
                else if (itemOrGroup is Item)
                {
                    var item = (Item)itemOrGroup;
                    item.Selected = check;
                }
            }
        }

        private void OnGroupUnchecked(object sender, RoutedEventArgs e)
        {
            this.HandleGroupCheck((CheckBox)sender, false);
        }

        private void CheckBox_Checked(object sender, RoutedEventArgs e)
        {
            this.HandleChildCheck((CheckBox)sender, true);
        }

        private void HandleChildCheck(CheckBox sender, bool check)
        {
            var group = (Item)sender.DataContext;
            group.IsSelected = true;
        }

        public static T GetVisualParent<t>(Visual referenceVisual) where T:Visual
        {
            Visual parent = referenceVisual;
            while (parent !=null)
            {
                parent = VisualTreeHelper.GetParent(parent) as Visual;
                if(parent !=null && parent.GetType() == typeof(T))
                {
                    return parent as T;
                }
            }
            return parent as T;
        }

        private void HandleChildGroupCheck(Item group, bool check)
        {
            //foreach (var itemOrGroup in group.Items)
            //{
            //    if (itemOrGroup is CollectionViewGroup)
            //    {
            //        // Found a nested group - recursively run this method again
            //        this.HandleGroupCheckRecursive(itemOrGroup as CollectionViewGroup, check);
            //    }
            //    else if (itemOrGroup is Item)
            //    {
            //        var item = (Item)itemOrGroup;
            //        item.Selected = check;
            //    }
            //}
        }

    }

    public class Item : INotifyPropertyChanged
    {
        private string _name;
        private bool _selected;
        private string _type;

        public string Name {
            get { return _name; }
            set {
                _name = value;
                this.OnPropertyChanged();
            }
        }

        public bool Selected {
            get { return _selected; }
            set {
                _selected = value;
                this.OnPropertyChanged();
            }
        }

        public string Type {
            get { return _type; }
            set {
                _type = value;
                this.OnPropertyChanged();
            }
        }

        bool? _isSelected;
        public bool? IsSelected {
            get { return _isSelected; }
            set {
                _isSelected = value;
                OnPropertyChanged("IsSelected");
            }
        }

        protected virtual void OnPropertyChanged([CallerMemberName] string property = "")
        {
            if (this.PropertyChanged != null) this.PropertyChanged(this, new PropertyChangedEventArgs(property));
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}

1 Ответов

Рейтинг:
0

Gerry Schmitz

Если вы хотите "Три-состояние", вам нужно определить свое связанное свойство как "nullable"; т. е.

public bool? Selected {
   get { return _selected; }
   set {
      _selected = value;
      this.OnPropertyChanged();
   }
}

("null" - это 3-е состояние).


sdileep1

Я добавил свойство "IsSelected" в свой код. Но я не могу отразить это в пользовательском интерфейсе. Я подозреваю, что здесь отсутствует какая-то логика. Я не могу установить родительский флажок на основе выбора дочернего элемента. Возможно, нужно добавить некоторую логику в метод HandleChildCheck(CheckBox sender, bool check), когда выбран дочерний элемент. Не могли бы вы помочь мне получить GroupItem из Collectionview, чтобы установить это.