可分组的选择框控件(MVVM下)(Toggle样式 仿造单选框RadioButton,复选框CheckBox功能)
分类:
IT文章
•
2023-11-17 16:01:30
原地址: http://www.cnblogs.com/yk250/p/5660340.html
效果图如下:支持分组的单选框,复选框样式和MVVM下功能的实现。这是项目中一个快捷键功能的扩展。

1,准备工作:VS2015 (15对WPF的支持变得异常的好,调试模式下允许自动更改属性。),随VS发布的Blend,几个基础类:
1 public class RelayCommand : ICommand
2 {
3 #region Fields
4
5 readonly Action<object> _executeAct;
6 readonly Predicate<object> _canExecutePre;
7 private readonly Action _execute;
8
9 private readonly Func<bool> _canExecute;
10 #endregion
11
12 #region Constructors
13
14 /// <summary>
15 /// Creates a new command that can always execute.
16 /// </summary>
17 /// <param name="execute">The execution logic.</param>
18 public RelayCommand(Action<object> execute)
19 : this(execute, null)
20 {
21 }
22
23 /// <summary>
24 /// Creates a new command.
25 /// </summary>
26 /// <param name="execute">The execution logic.</param>
27 /// <param name="canExecute">The execution status logic.</param>
28 public RelayCommand(Action<object> execute, Predicate<object> canExecute)
29 {
30 if (execute == null)
31 {
32 throw new ArgumentNullException("execute");
33 }
34
35 _executeAct = execute;
36 _canExecutePre = canExecute;
37 }
38
39
40 /// <summary>
41 /// Initializes a new instance of the RelayCommand class that
42 /// can always execute.
43 /// </summary>
44 /// <param name="execute">The execution logic.</param>
45 /// <exception cref="ArgumentNullException">If the execute argument is null.</exception>
46 public RelayCommand(Action execute)
47 : this(execute, null)
48 {
49 }
50
51 /// <summary>
52 /// Initializes a new instance of the RelayCommand class.
53 /// </summary>
54 /// <param name="execute">The execution logic.</param>
55 /// <param name="canExecute">The execution status logic.</param>
56 /// <exception cref="ArgumentNullException">If the execute argument is null.</exception>
57 public RelayCommand(Action execute, Func<bool> canExecute)
58 {
59 if (execute == null)
60 {
61 throw new ArgumentNullException("execute");
62 }
63
64 _execute = execute;
65 _canExecute = canExecute;
66 }
67
68 #endregion
69
70 #region ICommand Members
71
72 public bool CanExecute(object parameter)
73 {
74 if (parameter == null)
75 {
76 return _canExecute == null ? true : _canExecute();
77 }
78
79 return _canExecutePre == null ? true : _canExecutePre(parameter);
80 }
81
82 public event EventHandler CanExecuteChanged
83 {
84 add { CommandManager.RequerySuggested += value; }
85 remove { CommandManager.RequerySuggested -= value; }
86 }
87
88 public void Execute(object parameter)
89 {
90 if (!CanExecute(parameter))
91 return;
92 if (parameter == null)
93 {
94 if (_execute != null)
95 _execute();
96 return;
97 }
98 if (_executeAct != null)
99 _executeAct(parameter);
100
101 }
102
103 #endregion
104 }
View Code
1 public class ModelBase : INotifyPropertyChanged
2 {
3 /// <summary>
4 /// 属性改变事件
5 /// </summary>
6 public event PropertyChangedEventHandler PropertyChanged;
7
8 /// <summary>
9 /// 触发属性改变
10 /// </summary>
11 /// <param name="propertyName"></param>
12 protected virtual void RaisePropertyChangedEvent(string propertyName)
13 {
14 ///一般写法
15 // PropertyChangedEventHandler handler = this.PropertyChanged;
16 // if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
17 ///简易写法
18 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
19 }
20 }
View Code
2,前台XAML代码如下:
1 <Grid VerticalAlignment="Center" HorizontalAlignment="Center">
2 <Grid.RowDefinitions>
3 <RowDefinition></RowDefinition>
4 <RowDefinition></RowDefinition>
5 </Grid.RowDefinitions>
6 <Grid>
7 <ItemsControl Grid.Row="1" Margin="15 30 30 20" x:Name="IT" VerticalAlignment="CENTER" HorizontalAlignment="center" ItemsSource="{Binding SettingListsSingle}" Visibility="visiBLE">
8 <ItemsControl.ItemsPanel>
9 <ItemsPanelTemplate>
10 <StackPanel Orientation="Vertical" ></StackPanel>
11 </ItemsPanelTemplate>
12 </ItemsControl.ItemsPanel>
13 <ItemsControl.ItemTemplate>
14 <DataTemplate>
15 <Grid >
16 <Grid.ColumnDefinitions>
17 <ColumnDefinition Width="100"></ColumnDefinition>
18 <ColumnDefinition Width="AUTO"></ColumnDefinition>
19 </Grid.ColumnDefinitions>
20 <Grid Background="Brown" Tag="itgrid" x:Name="gr" Margin="0 0 5 0">
21 <Border BorderBrush="#FF00FF68" BorderThickness="0 0 0 2">
22 <TextBlock VerticalAlignment="Center" FontSize="16" Foreground="White" Text="{Binding Name}" TextBlock.TextAlignment="Center"></TextBlock>
23 </Border>
24 </Grid>
25 <ItemsControl x:Name="rowitems" Tag="{Binding GroupName}" HorizontalAlignment="Left" ItemsSource="{Binding TgLists}" Grid.Column="1" Margin="0 0 0 0">
26 <ItemsControl.ItemsPanel>
27 <ItemsPanelTemplate>
28 <StackPanel Orientation="Horizontal"></StackPanel>
29 </ItemsPanelTemplate>
30 </ItemsControl.ItemsPanel>
31 <ItemsControl.ItemTemplate>
32 <DataTemplate>
33 <Grid>
34 <Border BorderBrush="#437DE5" BorderThickness="0 0 0 2" Padding="2">
35 <ToggleButton Visibility="Visible" Command="{Binding CheckedCommand}" Margin="0" FontSize="15" CommandParameter="{Binding DataContext.GroupName,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ItemsControl}}" IsChecked="{Binding IsChecked}" MaxWidth="200" Style="{DynamicResource ToggleButtonStyle}" >
36 <ToggleButton.Resources>
37 <local:ParmsConverter x:Key="pc"></local:ParmsConverter>
38 </ToggleButton.Resources>
39 <ToggleButton.Content>
40 <TextBlock x:Name="tbcontent" TextWrapping="Wrap" Text="{Binding Content}">
41 </TextBlock>
42 </ToggleButton.Content>
43 </ToggleButton>
44 </Border>
45 </Grid>
46 </DataTemplate>
47 </ItemsControl.ItemTemplate>
48 </ItemsControl>
49 </Grid>
50 </DataTemplate>
51 </ItemsControl.ItemTemplate>
52 </ItemsControl>
53 </Grid>
54
55 <ItemsControl Grid.Row="1" Margin="15 30 30 20" x:Name="IT2" VerticalAlignment="CENTER" HorizontalAlignment="CENTER" ItemsSource="{Binding SettingLists}" Visibility="visiBLE">
56 <ItemsControl.ItemsPanel>
57 <ItemsPanelTemplate>
58 <StackPanel Orientation="Vertical" ></StackPanel>
59 </ItemsPanelTemplate>
60 </ItemsControl.ItemsPanel>
61 <ItemsControl.ItemTemplate>
62 <DataTemplate>
63 <Grid >
64 <Grid.ColumnDefinitions>
65 <ColumnDefinition Width="100"></ColumnDefinition>
66 <ColumnDefinition Width="AUTO"></ColumnDefinition>
67 </Grid.ColumnDefinitions>
68 <Grid Background="#437DE5" Tag="itgrid" x:Name="gr" Margin="0 0 5 0">
69 <Border BorderBrush="#FF00FF68" BorderThickness="0 0 0 2">
70 <TextBlock VerticalAlignment="Center" FontSize="16" Foreground="White" Text="{Binding Name}" TextBlock.TextAlignment="Center"></TextBlock>
71 </Border>
72 </Grid>
73 <ItemsControl x:Name="rowitems" Tag="{Binding GroupName}" HorizontalAlignment="Left" ItemsSource="{Binding TgLists}" Grid.Column="1" Margin="0 0 0 0">
74 <ItemsControl.ItemsPanel>
75 <ItemsPanelTemplate>
76 <StackPanel Orientation="Horizontal"></StackPanel>
77 </ItemsPanelTemplate>
78 </ItemsControl.ItemsPanel>
79 <ItemsControl.ItemTemplate>
80 <DataTemplate>
81 <Grid>
82 <Border BorderBrush="#437DE5" BorderThickness="0 0 0 2" Padding="2">
83 <ToggleButton Visibility="Visible" Command="{Binding CheckedCommand}" Margin="0" FontSize="15" CommandParameter="{Binding DataContext.GroupName,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ItemsControl}}" IsChecked="{Binding IsChecked}" MaxWidth="120" Style="{DynamicResource ToggleButtonStyle}" >
84 <ToggleButton.Resources>
85 <local:ParmsConverter x:Key="pc"></local:ParmsConverter>
86 </ToggleButton.Resources>
87 <!--<ToggleButton.CommandParameter>
88 <MultiBinding Converter="{StaticResource pc}">
89 <Binding Path="."></Binding>
90 <Binding Path="DataContext.GroupName" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ItemsControl}"></Binding>
91 </MultiBinding>
92 </ToggleButton.CommandParameter>-->
93 <ToggleButton.Content>
94 <TextBlock x:Name="tbcontent" TextWrapping="Wrap" Text="{Binding Content}">
95 </TextBlock>
96 </ToggleButton.Content>
97 </ToggleButton>
98
99
100
101 </Border>
102 <!--<Border BorderBrush="#437DE5" BorderThickness="0 0 0 2" Padding="2">
103 <RadioButton GroupName="{Binding Tag,ElementName=rowitems}" Checked="ToggleButton_Checked" Margin="0" FontSize="15" IsChecked="{Binding IsChecked}" MaxWidth="300" Content="{Binding Content}" Style="{DynamicResource ToggleButtonStyle}" />
104 </Border>-->
105 </Grid>
106 </DataTemplate>
107 </ItemsControl.ItemTemplate>
108 </ItemsControl>
109 </Grid>
110 </DataTemplate>
111 </ItemsControl.ItemTemplate>
112 </ItemsControl>
113 </Grid>
View Code
使用的主要样式如下:(一般用Blend完成,这里加入了2个进入和退场动画)
1 <Style x:Key="ToggleButtonStyle" TargetType="{x:Type ToggleButton}">
2 <!--<Setter Property="MaxHeight" Value="></Setter>-->
3 <Setter Property="Template">
4 <Setter.Value>
5 <ControlTemplate TargetType="{x:Type ToggleButton}">
6 <ControlTemplate.Resources>
7 <SolidColorBrush x:Key="pathcolor" Color="#FF21A621"></SolidColorBrush>
8 <SolidColorBrush x:Key="buttonuncheckedcolor" Color="#FF767A76"></SolidColorBrush>
9 <SolidColorBrush x:Key="buttoncheckedcolor"></SolidColorBrush>
10 <SolidColorBrush x:Key="headercolor"></SolidColorBrush>
11 <Storyboard x:Key="Unchecked">
12 <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="grid">
13 <EasingColorKeyFrame KeyTime="0" Value="#FF21A621"/>
14 <EasingColorKeyFrame KeyTime="0:0:0.3" Value="sc#1, 0.114781961, 0.269301116, 0.114781961"/>
15 <EasingColorKeyFrame KeyTime="0:0:0.5" Value="Gray"/>
16 </ColorAnimationUsingKeyFrames>
17 <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="br">
18 <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
19 <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="30"/>
20 </DoubleAnimationUsingKeyFrames>
21 <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Width)" Storyboard.TargetName="br">
22 <EasingDoubleKeyFrame KeyTime="0" Value="20"/>
23 <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="0"/>
24 </DoubleAnimationUsingKeyFrames>
25 <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="br">
26 <EasingDoubleKeyFrame KeyTime="0" Value="20"/>
27 <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="0"/>
28 </DoubleAnimationUsingKeyFrames>
29 <ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Margin)" Storyboard.TargetName="br">
30 <EasingThicknessKeyFrame KeyTime="0" Value="5,2"/>
31 <EasingThicknessKeyFrame KeyTime="0:0:0.3" Value="0,2"/>
32 </ThicknessAnimationUsingKeyFrames>
33 <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="checkBox">
34 <EasingDoubleKeyFrame KeyTime="0" Value="100"/>
35 <EasingDoubleKeyFrame KeyTime="0:0:0.1" Value="0"/>
36 <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="0"/>
37 </DoubleAnimationUsingKeyFrames>
38 <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" Storyboard.TargetName="br">
39 <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
40 <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="1"/>
41 </DoubleAnimationUsingKeyFrames>
42 <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" Storyboard.TargetName="br">
43 <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
44 <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="1"/>
45 </DoubleAnimationUsingKeyFrames>
46 </Storyboard>
47 <Storyboard x:Key="Checked">
48 <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="grid">
49 <SplineColorKeyFrame KeyTime="0" Value="#FF767A76"/>
50 <SplineColorKeyFrame KeyTime="0:0:0.2" Value="sc#1, 0.114781961, 0.269301116, 0.114781961"/>
51 <SplineColorKeyFrame KeyTime="0:0:0.5" Value="#FF21A621"/>
52 </ColorAnimationUsingKeyFrames>
53 <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="br">
54 <SplineDoubleKeyFrame KeyTime="0" Value="30"/>
55 <SplineDoubleKeyFrame KeyTime="0:0:0.4" Value="0"/>
56 </DoubleAnimationUsingKeyFrames>
57 <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Width)" Storyboard.TargetName="br">
58 <SplineDoubleKeyFrame KeyTime="0" Value="0"/>
59 <SplineDoubleKeyFrame KeyTime="0:0:0.4" Value="20"/>
60 </DoubleAnimationUsingKeyFrames>
61 <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="br">
62 <SplineDoubleKeyFrame KeyTime="0" Value="0"/>
63 <SplineDoubleKeyFrame KeyTime="0:0:0.4" Value="20"/>
64 </DoubleAnimationUsingKeyFrames>
65 <ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Margin)" Storyboard.TargetName="br">
66 <SplineThicknessKeyFrame KeyTime="0" Value="0,2"/>
67 <SplineThicknessKeyFrame KeyTime="0:0:0.4" Value="5,2"/>
68 </ThicknessAnimationUsingKeyFrames>
69 <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="checkBox">
70 <SplineDoubleKeyFrame KeyTime="0" Value="0"/>
71 <SplineDoubleKeyFrame KeyTime="0:0:0.3" Value="0"/>
72 <SplineDoubleKeyFrame KeyTime="0:0:0.4" Value="100"/>
73 </DoubleAnimationUsingKeyFrames>
74 <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" Storyboard.TargetName="br">
75 <SplineDoubleKeyFrame KeyTime="0" Value="1"/>
76 <SplineDoubleKeyFrame KeyTime="0:0:0.4" Value="1"/>
77 </DoubleAnimationUsingKeyFrames>
78 <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" Storyboard.TargetName="br">
79 <SplineDoubleKeyFrame KeyTime="0" Value="1"/>
80 <SplineDoubleKeyFrame KeyTime="0:0:0.4" Value="1"/>
81 </DoubleAnimationUsingKeyFrames>
82 </Storyboard>
83 </ControlTemplate.Resources>
84 <Grid x:Name="grid" Height="AUTO" Width="AUTO" Background="{StaticResource buttonuncheckedcolor}">
85 <Grid.ColumnDefinitions>
86 <ColumnDefinition Width="*"></ColumnDefinition>
87 <ColumnDefinition Width="AUTO"></ColumnDefinition>
88 </Grid.ColumnDefinitions>
89 <Border Padding="5">
90 <Label TextElement.Foreground="WHITE" Content="{TemplateBinding Content}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center" Margin="0 0 0 0" MaxWidth="{TemplateBinding MaxWidth}"/>
91 </Border>
92 <Border Grid.Column="1" Opacity="1" x:Name="br" VerticalAlignment="CENTER" HorizontalAlignment="CENTER" Margin="0 2" BorderThickness="2" Background="White" CornerRadius="15" RenderTransformOrigin="0.5,0.5" Height="0" Width="0" >
93 <Border.RenderTransform>
94 <TransformGroup>
95 <ScaleTransform ScaleX="0" ScaleY="0"/>
96 <SkewTransform/>
97 <RotateTransform/>
98 <TranslateTransform/>
99 </TransformGroup>
100 </Border.RenderTransform>
101 <Path Margin="2" x:Name="checkBox" UseLayoutRounding="False" Stretch="Fill" Opacity="100" Fill="{StaticResource pathcolor}" Data="M 1145.607177734375,430 C1145.607177734375,430 1141.449951171875,435.0772705078125 1141.449951171875,435.0772705078125 1141.449951171875,435.0772705078125 1139.232177734375,433.0999755859375 1139.232177734375,433.0999755859375 1139.232177734375,433.0999755859375 1138,434.5538330078125 1138,434.5538330078125 1138,434.5538330078125 1141.482177734375,438 1141.482177734375,438 1141.482177734375,438 1141.96875,437.9375 1141.96875,437.9375 1141.96875,437.9375 1147,431.34619140625 1147,431.34619140625 1147,431.34619140625 1145.607177734375,430 1145.607177734375,430 z"/>
102 </Border>
103
104 </Grid>
105 <ControlTemplate.Triggers>
106 <!--<EventTrigger RoutedEvent="FrameworkElement.Loaded">
107 <BeginStoryboard Storyboard="{StaticResource Unchecked_Copy2}"/>
108 </EventTrigger>-->
109 <Trigger Property="IsChecked" Value="true">
110 <Trigger.EnterActions>
111 <BeginStoryboard Storyboard="{StaticResource Checked}"></BeginStoryboard>
112 </Trigger.EnterActions>
113 <Trigger.ExitActions>
114 <BeginStoryboard Storyboard="{StaticResource Unchecked}"></BeginStoryboard>
115 </Trigger.ExitActions>
116 </Trigger>
117 <!--<EventTrigger RoutedEvent="ToggleButton.Unchecked">
118 <BeginStoryboard Storyboard="{StaticResource Unchecked}"/>
119 </EventTrigger>
120 <EventTrigger RoutedEvent="ToggleButton.Checked">
121 <BeginStoryboard x:Name="Unchecked_Copy2_BeginStoryboard" Storyboard="{StaticResource Unchecked_Copy2}"/>
122 </EventTrigger>-->
123 </ControlTemplate.Triggers>
124 </ControlTemplate>
125 </Setter.Value>
126 </Setter>
127 </Style>
View Code
样式和颜色都是根据自己喜好来的,可以随意修改的。关键点事要用Path画出选中的钩,然后通过数据触发器将选中和不选中的姿态通过动画来展示:
<Trigger Property="IsChecked" Value="true">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource Checked}"></BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource Unchecked}"></BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
3,定义ViewModel和相关结构:
首先是定义选中的3个状态:多行多选,多行单选,以及单行单选。(其它类型请自行添加和实现。)
public enum CheckType
{
MutilChecked,
SingleChecked,
RowChecked
}
然后是 设计层次结构:通用来讲我这里粗略的设计成嵌套类型,即数据源为List<setmodel>类型,而setmodel中又包含ObservableCollection<tgmodel>类型,而这个tgmodel呢,其实就是精确到的每一个按钮对应的模型了。下面给出具体定义:
1 public class setmodel : ModelBase
2 {
3 private string _name;
4 /// <summary>
5 /// 显示名称
6 /// </summary>
7 public string Name
8 {
9 get { return _name; }
10 set
11 {
12 _name = value;
13 RaisePropertyChangedEvent("Name");
14 }
15 }
16
17 private string _groupname = "singlecheck";
18 /// <summary>
19 /// 显示名称
20 /// </summary>
21 public string GroupName
22 {
23 get { return _groupname; }
24 set
25 {
26 _groupname = value;
27 RaisePropertyChangedEvent("GroupName");
28 }
29 }
30 public ObservableCollection<tgmodel> TgLists { get; set; }
31
32
33 }
View Code
1 public class tgmodel : ModelBase
2 {
3 public tgmodel()
4 {
5 CommandDefine = new CommandDefine();
6 }
7 private string content;
8 /// <summary>
9 /// Toggle按钮显示内容
10 /// </summary>
11 public string Content
12 {
13 get { return content; }
14 set
15 {
16 content = value;
17 RaisePropertyChangedEvent("Content");
18 }
19 }
20
21
22 private bool ischecked;
23 /// <summary>
24 /// 是否选中
25 /// </summary>
26 public bool IsChecked
27 {
28 get { return ischecked; }
29 set
30 {
31 ischecked = value;
32 RaisePropertyChangedEvent("IsChecked");
33 }
34 }
35 public ICommand CheckedCommand { get; set; }
36 public CommandDefine CommandDefine { get; set; }
37 }
View Code
然后这里写了一个队togglebutton 信息的辅助类:主要是封装了togglebutton对应的模型 TgModel,它所在组的 上一级模型 SetModel,所在行的名称 RowName。
public class TgInfo
{
public tgmodel TgModel { get; set; }
public setmodel SetModel { get; set; }
public string RowName { get; set; }
//public CheckType CheckType { get; set; }
//public List<setmodel> SourceLists { get; set; }
}
4,最后就是功能的实现了,这里代码有点乱,还有进一步修改的可能。
(1)初始化DataContext,先是ViewModel:
SettingListsSingle 是我上面单行拿来做选择项的集合,下面的三行数据数据源则是
SettingLists。
1 public class ViewModel : ModelBase
2 {
3 /// <summary>
4 /// 设置列表
5 /// </summary>
6 public List<setmodel> SettingLists { get; set; }
7 public List<setmodel> SettingListsSingle { get; set; }
8
9 private CheckType _checktype;
10 /// <summary>
11 /// 选项类型
12 /// </summary>
13 public CheckType CheckType
14 {
15 get { return _checktype; }
16 set
17 {
18 _checktype = value;
19 RaisePropertyChangedEvent("CheckType");
20 }
21 }
22
23 private CheckType _testchecktype;
24 /// <summary>
25 /// 选项类型
26 /// </summary>
27 public CheckType TestCheckType
28 {
29 get { return _testchecktype; }
30 set
31 {
32 _testchecktype = value;
33 RaisePropertyChangedEvent("TestCheckType");
34 }
35 }
36
37 }
初始化ViewModel,后台代码:
1 DataContext = new ViewModel()
2 {
3 TestCheckType = CheckType.SingleChecked,
4 SettingListsSingle = new List<setmodel>() {
5 new setmodel() {
6 GroupName="GN0",
7 Name="选中类型",
8 TgLists =new ObservableCollection<tgmodel>()
9 { new tgmodel() { Content="多选"},
10 new tgmodel() { Content="行单选"},
11 new tgmodel() { Content="全部单选" ,IsChecked=true },
12 }}, },
13 CheckType = CheckType.RowChecked,
14 SettingLists = new List<setmodel>() {
15 new setmodel() {
16 GroupName="GN1",
17 Name="测试数字",
18 TgLists =new ObservableCollection<tgmodel>()
19 { new tgmodel() { Content="Test1"},
20 new tgmodel() { Content="Test2"},
21 new tgmodel() { Content="Test3"},
22 new tgmodel() { Content="Test4"},
23 new tgmodel() { Content="Test5",IsChecked=true},
24 }},
25 new setmodel() {
26 GroupName ="GN2",
27 Name="测试字母",
28 TgLists =new ObservableCollection<tgmodel>()
29 { new tgmodel() { Content="TestA"},
30 new tgmodel() { Content="TestB"},
31 new tgmodel() { Content="TestC"},
32 new tgmodel() { Content="TestD"},
33 new tgmodel() { Content="TestE",IsChecked=true},
34 }},
35 new setmodel() {
36 GroupName="GN3",
37 Name="测试假名",
38 TgLists =new ObservableCollection<tgmodel>()
39 { new tgmodel() { Content="Testあ"},
40 new tgmodel() { Content="Testい"},
41 new tgmodel() { Content="Testう"},
42 new tgmodel() { Content="Testえ"},
43 new tgmodel() { Content="Testお",IsChecked=true},
44 }},
45 }
46 };
最后是命令的初始化:
1 var Vm = (DataContext as ViewModel);
2
3 Vm.SettingLists.ForEach(setmodel => setmodel.TgLists.ToList().ForEach(
4 (tgmodel=> tgmodel.CheckedCommand = new RelayCommand((pars) =>
5 {
6 TgInfo info = new TgInfo
7 {
8 RowName = pars.ToString(),
9 SetModel = setmodel,
10 TgModel = tgmodel
11 };
12 SetTgStatus(info, Vm,Vm.CheckType, Vm.SettingLists);
13 }))));
14
15
16
17 Vm.SettingListsSingle.ForEach(setmodel => setmodel.TgLists.ToList().ForEach(
18 (tgmodel => tgmodel.CheckedCommand = new RelayCommand((pars) =>
19 {
20 TgInfo info = new TgInfo
21 {
22 RowName = pars.ToString(),
23 SetModel = setmodel,
24 TgModel = tgmodel
25 };
26 SetTgStatus(info, Vm, Vm.TestCheckType, Vm.SettingListsSingle);
27 }))));
设置命令实现如下:这里只是我的实现。
1 /// <summary>
2 /// 设置选中状态
3 /// </summary>
4 /// <param name="pars"></param>
5 /// <param name="Vm"></param>
6 private void SetTgStatus(params object[] parms)
7 {
8 var tginfo = parms[0] as TgInfo;
9 var tgmodel = tginfo.TgModel;
10 var rowname = tginfo.RowName;
11 var setmodel = tginfo.SetModel;
12 var Vm = parms[1] as ViewModel;
13 var checktype = (CheckType)parms[2];
14 var settings = parms[3] as List<setmodel>;
15 if (setmodel.Name=="选中类型")
16 {
17 var index = setmodel.TgLists.IndexOf(tgmodel);
18 Vm.CheckType = this[index];
19 }
20 if (checktype == CheckType.RowChecked)
21 {
22 settings.ForEach(sets =>
23 sets.TgLists.Where
24 (t => rowname == sets.GroupName&& t!=tgmodel).ToList().
25 ForEach(tg => tg.IsChecked = false));
26 }
27 else if (checktype == CheckType.SingleChecked)
28 {
29 settings.ForEach(sets =>
30 sets.TgLists.Where(t=>t!=tgmodel).ToList().
31 ForEach(tg => tg.IsChecked = false));
32 }
33 else
34 {
35
36 }
37 }
其中CheckType 用到了索引器,实现如下:
1 public CheckType this[int index]
2 {
3 get
4 {
5 return index == 0 ? CheckType.MutilChecked :
6 (index == 1 ? CheckType.RowChecked :
7 CheckType.SingleChecked);
8 }
9
10 set
11 {
12 }
13 }
5,运行,OK。有什么问题可以一起讨论!
现在开始坚持每天一贴!也算是项目经验的总结和分享吧。当然肯定有很多不足之处,希望大家多多指教!