zoukankan      html  css  js  c++  java
  • 可分组的选择框控件(MVVM下)(Toggle样式 仿造单选框RadioButton,复选框CheckBox功能)

    原地址: 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。有什么问题可以一起讨论!

    现在开始坚持每天一贴!也算是项目经验的总结和分享吧。当然肯定有很多不足之处,希望大家多多指教!

  • 相关阅读:
    http1.1长连接实战(一)
    【转】微服务与SOA之间差了一个ESB
    在SpringBoot 1.5.3上使用gradle引入hikariCP
    狮子心
    为啥他们不作为
    Redis 后台运行
    Jquery 动态生成的元素绑定事件
    linux tzselect 设置时区
    Docker 容器内配置Tomcat manager 远程控制
    Docker基于容器创建镜像
  • 原文地址:https://www.cnblogs.com/yk250/p/5660340.html
Copyright © 2011-2022 走看看