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

1,准备工作:VS2015 (15对WPF的支持变得异常的好,调试模式下允许自动更改属性。),随VS发布的Blend,几个基础类:
public class RelayCommand : ICommand
{
#region Fields readonly Action<object> _executeAct;
readonly Predicate<object> _canExecutePre;
private readonly Action _execute; private readonly Func<bool> _canExecute;
#endregion #region Constructors /// <summary>
/// Creates a new command that can always execute.
/// </summary>
/// <param name="execute">The execution logic.</param>
public RelayCommand(Action<object> execute)
: this(execute, null)
{
} /// <summary>
/// Creates a new command.
/// </summary>
/// <param name="execute">The execution logic.</param>
/// <param name="canExecute">The execution status logic.</param>
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
{
throw new ArgumentNullException("execute");
} _executeAct = execute;
_canExecutePre = canExecute;
} /// <summary>
/// Initializes a new instance of the RelayCommand class that
/// can always execute.
/// </summary>
/// <param name="execute">The execution logic.</param>
/// <exception cref="ArgumentNullException">If the execute argument is null.</exception>
public RelayCommand(Action execute)
: this(execute, null)
{
} /// <summary>
/// Initializes a new instance of the RelayCommand class.
/// </summary>
/// <param name="execute">The execution logic.</param>
/// <param name="canExecute">The execution status logic.</param>
/// <exception cref="ArgumentNullException">If the execute argument is null.</exception>
public RelayCommand(Action execute, Func<bool> canExecute)
{
if (execute == null)
{
throw new ArgumentNullException("execute");
} _execute = execute;
_canExecute = canExecute;
} #endregion #region ICommand Members public bool CanExecute(object parameter)
{
if (parameter == null)
{
return _canExecute == null ? true : _canExecute();
} return _canExecutePre == null ? true : _canExecutePre(parameter);
} public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
} public void Execute(object parameter)
{
if (!CanExecute(parameter))
return;
if (parameter == null)
{
if (_execute != null)
_execute();
return;
}
if (_executeAct != null)
_executeAct(parameter); } #endregion
}
public class ModelBase : INotifyPropertyChanged
{
/// <summary>
/// 属性改变事件
/// </summary>
public event PropertyChangedEventHandler PropertyChanged; /// <summary>
/// 触发属性改变
/// </summary>
/// <param name="propertyName"></param>
protected virtual void RaisePropertyChangedEvent(string propertyName)
{
///一般写法
// PropertyChangedEventHandler handler = this.PropertyChanged;
// if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
///简易写法
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
2,前台XAML代码如下:
<Grid VerticalAlignment="Center" HorizontalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid>
<ItemsControl Grid.Row="1" Margin="15 30 30 20" x:Name="IT" VerticalAlignment="CENTER" HorizontalAlignment="center" ItemsSource="{Binding SettingListsSingle}" Visibility="visiBLE">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" ></StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"></ColumnDefinition>
<ColumnDefinition Width="AUTO"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid Background="Brown" Tag="itgrid" x:Name="gr" Margin="0 0 5 0">
<Border BorderBrush="#FF00FF68" BorderThickness="0 0 0 2">
<TextBlock VerticalAlignment="Center" FontSize="16" Foreground="White" Text="{Binding Name}" TextBlock.TextAlignment="Center"></TextBlock>
</Border>
</Grid>
<ItemsControl x:Name="rowitems" Tag="{Binding GroupName}" HorizontalAlignment="Left" ItemsSource="{Binding TgLists}" Grid.Column="1" Margin="0 0 0 0">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"></StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Border BorderBrush="#437DE5" BorderThickness="0 0 0 2" Padding="2">
<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}" >
<ToggleButton.Resources>
<local:ParmsConverter x:Key="pc"></local:ParmsConverter>
</ToggleButton.Resources>
<ToggleButton.Content>
<TextBlock x:Name="tbcontent" TextWrapping="Wrap" Text="{Binding Content}">
</TextBlock>
</ToggleButton.Content>
</ToggleButton>
</Border>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid> <ItemsControl Grid.Row="1" Margin="15 30 30 20" x:Name="IT2" VerticalAlignment="CENTER" HorizontalAlignment="CENTER" ItemsSource="{Binding SettingLists}" Visibility="visiBLE">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" ></StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"></ColumnDefinition>
<ColumnDefinition Width="AUTO"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid Background="#437DE5" Tag="itgrid" x:Name="gr" Margin="0 0 5 0">
<Border BorderBrush="#FF00FF68" BorderThickness="0 0 0 2">
<TextBlock VerticalAlignment="Center" FontSize="16" Foreground="White" Text="{Binding Name}" TextBlock.TextAlignment="Center"></TextBlock>
</Border>
</Grid>
<ItemsControl x:Name="rowitems" Tag="{Binding GroupName}" HorizontalAlignment="Left" ItemsSource="{Binding TgLists}" Grid.Column="1" Margin="0 0 0 0">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"></StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Border BorderBrush="#437DE5" BorderThickness="0 0 0 2" Padding="2">
<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}" >
<ToggleButton.Resources>
<local:ParmsConverter x:Key="pc"></local:ParmsConverter>
</ToggleButton.Resources>
<!--<ToggleButton.CommandParameter>
<MultiBinding Converter="{StaticResource pc}">
<Binding Path="."></Binding>
<Binding Path="DataContext.GroupName" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ItemsControl}"></Binding>
</MultiBinding>
</ToggleButton.CommandParameter>-->
<ToggleButton.Content>
<TextBlock x:Name="tbcontent" TextWrapping="Wrap" Text="{Binding Content}">
</TextBlock>
</ToggleButton.Content>
</ToggleButton> </Border>
<!--<Border BorderBrush="#437DE5" BorderThickness="0 0 0 2" Padding="2">
<RadioButton GroupName="{Binding Tag,ElementName=rowitems}" Checked="ToggleButton_Checked" Margin="0" FontSize="15" IsChecked="{Binding IsChecked}" MaxWidth="300" Content="{Binding Content}" Style="{DynamicResource ToggleButtonStyle}" />
</Border>-->
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
使用的主要样式如下:(一般用Blend完成,这里加入了2个进入和退场动画)
<Style x:Key="ToggleButtonStyle" TargetType="{x:Type ToggleButton}">
<!--<Setter Property="MaxHeight" Value="></Setter>-->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<ControlTemplate.Resources>
<SolidColorBrush x:Key="pathcolor" Color="#FF21A621"></SolidColorBrush>
<SolidColorBrush x:Key="buttonuncheckedcolor" Color="#FF767A76"></SolidColorBrush>
<SolidColorBrush x:Key="buttoncheckedcolor"></SolidColorBrush>
<SolidColorBrush x:Key="headercolor"></SolidColorBrush>
<Storyboard x:Key="Unchecked">
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="grid">
<EasingColorKeyFrame KeyTime="0" Value="#FF21A621"/>
<EasingColorKeyFrame KeyTime="0:0:0.3" Value="sc#1, 0.114781961, 0.269301116, 0.114781961"/>
<EasingColorKeyFrame KeyTime="0:0:0.5" Value="Gray"/>
</ColorAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="br">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="30"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Width)" Storyboard.TargetName="br">
<EasingDoubleKeyFrame KeyTime="0" Value="20"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="br">
<EasingDoubleKeyFrame KeyTime="0" Value="20"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Margin)" Storyboard.TargetName="br">
<EasingThicknessKeyFrame KeyTime="0" Value="5,2"/>
<EasingThicknessKeyFrame KeyTime="0:0:0.3" Value="0,2"/>
</ThicknessAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="checkBox">
<EasingDoubleKeyFrame KeyTime="0" Value="100"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.1" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" Storyboard.TargetName="br">
<EasingDoubleKeyFrame KeyTime="0" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" Storyboard.TargetName="br">
<EasingDoubleKeyFrame KeyTime="0" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Checked">
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="grid">
<SplineColorKeyFrame KeyTime="0" Value="#FF767A76"/>
<SplineColorKeyFrame KeyTime="0:0:0.2" Value="sc#1, 0.114781961, 0.269301116, 0.114781961"/>
<SplineColorKeyFrame KeyTime="0:0:0.5" Value="#FF21A621"/>
</ColorAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="br">
<SplineDoubleKeyFrame KeyTime="0" Value="30"/>
<SplineDoubleKeyFrame KeyTime="0:0:0.4" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Width)" Storyboard.TargetName="br">
<SplineDoubleKeyFrame KeyTime="0" Value="0"/>
<SplineDoubleKeyFrame KeyTime="0:0:0.4" Value="20"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="br">
<SplineDoubleKeyFrame KeyTime="0" Value="0"/>
<SplineDoubleKeyFrame KeyTime="0:0:0.4" Value="20"/>
</DoubleAnimationUsingKeyFrames>
<ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Margin)" Storyboard.TargetName="br">
<SplineThicknessKeyFrame KeyTime="0" Value="0,2"/>
<SplineThicknessKeyFrame KeyTime="0:0:0.4" Value="5,2"/>
</ThicknessAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="checkBox">
<SplineDoubleKeyFrame KeyTime="0" Value="0"/>
<SplineDoubleKeyFrame KeyTime="0:0:0.3" Value="0"/>
<SplineDoubleKeyFrame KeyTime="0:0:0.4" Value="100"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" Storyboard.TargetName="br">
<SplineDoubleKeyFrame KeyTime="0" Value="1"/>
<SplineDoubleKeyFrame KeyTime="0:0:0.4" Value="1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" Storyboard.TargetName="br">
<SplineDoubleKeyFrame KeyTime="0" Value="1"/>
<SplineDoubleKeyFrame KeyTime="0:0:0.4" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<Grid x:Name="grid" Height="AUTO" Width="AUTO" Background="{StaticResource buttonuncheckedcolor}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="AUTO"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Border Padding="5">
<Label TextElement.Foreground="WHITE" Content="{TemplateBinding Content}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center" Margin="0 0 0 0" MaxWidth="{TemplateBinding MaxWidth}"/>
</Border>
<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" >
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="0" ScaleY="0"/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Border.RenderTransform>
<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"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<!--<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Storyboard="{StaticResource Unchecked_Copy2}"/>
</EventTrigger>-->
<Trigger Property="IsChecked" Value="true">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource Checked}"></BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource Unchecked}"></BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
<!--<EventTrigger RoutedEvent="ToggleButton.Unchecked">
<BeginStoryboard Storyboard="{StaticResource Unchecked}"/>
</EventTrigger>
<EventTrigger RoutedEvent="ToggleButton.Checked">
<BeginStoryboard x:Name="Unchecked_Copy2_BeginStoryboard" Storyboard="{StaticResource Unchecked_Copy2}"/>
</EventTrigger>-->
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
样式和颜色都是根据自己喜好来的,可以随意修改的。关键点事要用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呢,其实就是精确到的每一个按钮对应的模型了。下面给出具体定义:
public class setmodel : ModelBase
{
private string _name;
/// <summary>
/// 显示名称
/// </summary>
public string Name
{
get { return _name; }
set
{
_name = value;
RaisePropertyChangedEvent("Name");
}
} private string _groupname = "singlecheck";
/// <summary>
/// 显示名称
/// </summary>
public string GroupName
{
get { return _groupname; }
set
{
_groupname = value;
RaisePropertyChangedEvent("GroupName");
}
}
public ObservableCollection<tgmodel> TgLists { get; set; } }
public class tgmodel : ModelBase
{
public tgmodel()
{
CommandDefine = new CommandDefine();
}
private string content;
/// <summary>
/// Toggle按钮显示内容
/// </summary>
public string Content
{
get { return content; }
set
{
content = value;
RaisePropertyChangedEvent("Content");
}
} private bool ischecked;
/// <summary>
/// 是否选中
/// </summary>
public bool IsChecked
{
get { return ischecked; }
set
{
ischecked = value;
RaisePropertyChangedEvent("IsChecked");
}
}
public ICommand CheckedCommand { get; set; }
public CommandDefine CommandDefine { get; set; }
}
然后这里写了一个队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。
public class ViewModel : ModelBase
{
/// <summary>
/// 设置列表
/// </summary>
public List<setmodel> SettingLists { get; set; }
public List<setmodel> SettingListsSingle { get; set; } private CheckType _checktype;
/// <summary>
/// 选项类型
/// </summary>
public CheckType CheckType
{
get { return _checktype; }
set
{
_checktype = value;
RaisePropertyChangedEvent("CheckType");
}
} private CheckType _testchecktype;
/// <summary>
/// 选项类型
/// </summary>
public CheckType TestCheckType
{
get { return _testchecktype; }
set
{
_testchecktype = value;
RaisePropertyChangedEvent("TestCheckType");
}
} }
初始化ViewModel,后台代码:
DataContext = new ViewModel()
{
TestCheckType = CheckType.SingleChecked,
SettingListsSingle = new List<setmodel>() {
new setmodel() {
GroupName="GN0",
Name="选中类型",
TgLists =new ObservableCollection<tgmodel>()
{ new tgmodel() { Content="多选"},
new tgmodel() { Content="行单选"},
new tgmodel() { Content="全部单选" ,IsChecked=true },
}}, },
CheckType = CheckType.RowChecked,
SettingLists = new List<setmodel>() {
new setmodel() {
GroupName="GN1",
Name="测试数字",
TgLists =new ObservableCollection<tgmodel>()
{ new tgmodel() { Content="Test1"},
new tgmodel() { Content="Test2"},
new tgmodel() { Content="Test3"},
new tgmodel() { Content="Test4"},
new tgmodel() { Content="Test5",IsChecked=true},
}},
new setmodel() {
GroupName ="GN2",
Name="测试字母",
TgLists =new ObservableCollection<tgmodel>()
{ new tgmodel() { Content="TestA"},
new tgmodel() { Content="TestB"},
new tgmodel() { Content="TestC"},
new tgmodel() { Content="TestD"},
new tgmodel() { Content="TestE",IsChecked=true},
}},
new setmodel() {
GroupName="GN3",
Name="测试假名",
TgLists =new ObservableCollection<tgmodel>()
{ new tgmodel() { Content="Testあ"},
new tgmodel() { Content="Testい"},
new tgmodel() { Content="Testう"},
new tgmodel() { Content="Testえ"},
new tgmodel() { Content="Testお",IsChecked=true},
}},
}
};
最后是命令的初始化:
var Vm = (DataContext as ViewModel); Vm.SettingLists.ForEach(setmodel => setmodel.TgLists.ToList().ForEach(
(tgmodel=> tgmodel.CheckedCommand = new RelayCommand((pars) =>
{
TgInfo info = new TgInfo
{
RowName = pars.ToString(),
SetModel = setmodel,
TgModel = tgmodel
};
SetTgStatus(info, Vm,Vm.CheckType, Vm.SettingLists);
})))); Vm.SettingListsSingle.ForEach(setmodel => setmodel.TgLists.ToList().ForEach(
(tgmodel => tgmodel.CheckedCommand = new RelayCommand((pars) =>
{
TgInfo info = new TgInfo
{
RowName = pars.ToString(),
SetModel = setmodel,
TgModel = tgmodel
};
SetTgStatus(info, Vm, Vm.TestCheckType, Vm.SettingListsSingle);
}))));
设置命令实现如下:这里只是我的实现。
/// <summary>
/// 设置选中状态
/// </summary>
/// <param name="pars"></param>
/// <param name="Vm"></param>
private void SetTgStatus(params object[] parms)
{
var tginfo = parms[] as TgInfo;
var tgmodel = tginfo.TgModel;
var rowname = tginfo.RowName;
var setmodel = tginfo.SetModel;
var Vm = parms[] as ViewModel;
var checktype = (CheckType)parms[];
var settings = parms[] as List<setmodel>;
if (setmodel.Name=="选中类型")
{
var index = setmodel.TgLists.IndexOf(tgmodel);
Vm.CheckType = this[index];
}
if (checktype == CheckType.RowChecked)
{
settings.ForEach(sets =>
sets.TgLists.Where
(t => rowname == sets.GroupName&& t!=tgmodel).ToList().
ForEach(tg => tg.IsChecked = false));
}
else if (checktype == CheckType.SingleChecked)
{
settings.ForEach(sets =>
sets.TgLists.Where(t=>t!=tgmodel).ToList().
ForEach(tg => tg.IsChecked = false));
}
else
{ }
}
其中CheckType 用到了索引器,实现如下:
public CheckType this[int index]
{
get
{
return index == ? CheckType.MutilChecked :
(index == ? CheckType.RowChecked :
CheckType.SingleChecked);
} set
{
}
}
5,运行,OK。有什么问题可以一起讨论!
现在开始坚持每天一贴!也算是项目经验的总结和分享吧。当然肯定有很多不足之处,希望大家多多指教!
可分组的选择框控件(MVVM下)(Toggle样式 仿造单选框RadioButton,复选框CheckBox功能)的更多相关文章
- Qt树形控件QTreeView使用1——节点的添加删除操作 复选框的设置
QtreeView是ui中最常用的控件,Qt中QTreeWidget比QTreeView更简单,但没有QTreeView那么灵活(QTreeWidget封装的和MFC的CTreeCtrl很类似,没有m ...
- MFC的组合框(ComboBox)控件切换下拉样式
由于课题的需求需要做MFC串口程序,看了百度下载的串口助手的界面风格,发现这个设计很好 波特率的组合框只给出了5个可选数值,然后第6个选项是Custom,即手动输入. 实际上DCB结构的BaudRat ...
- checkbox复选框和div click事件重叠,点击div后复选框也被选中,同时改变div颜色,否则则不选中
checkbox复选框和div click事件重叠,点击div后复选框也被选中,同时改变div颜色,否则则不选中 <!DOCTYPE html> <html lang=" ...
- bootstrap-multiselect 设置单选无效(设置单选依然是复选框)
bootstrap-multiselect 的使用介绍:https://www.cnblogs.com/landeanfen/p/5013452.html bootstrap-multiselect ...
- bootstrap table 复选框选中后,翻页不影响已选中的复选框
使用的 jquery版本为 2.1.1 在项目中发现bootstrap table的复选框选中后,翻页操作会导致上一页选中的丢失,api中的 bootstrapTable('getSelections ...
- Android_(控件)使用AlertDialog实现点击Button显示出多选框
单击"更多"按钮,显示出多选框 运行截图: 程序结构 (本想通过Button中android:background使用drawable资源下的图片作为按钮背景,设计太丑就去掉了Σ( ...
- css 设置 checkbox复选框控件的对勾√样式
效果 最终的样式,想要的效果: 我们要创建方框中的对勾,对于这一点,我们可以使用:after伪类创建一个新的元素,为了实现这个样式,我们可以创建一个5px * 15px的长方形并给他加上边框. ...
- Qt — tableWidget插入复选框
之前不太了解Qt中的相关控件,一直尝试直接在tableview上增加复选框. 但相对来说,在tableview增加复选框的工作量与麻烦程度远超tableWidget. 接下来是如何在Qt的tableW ...
- 关于bootstrap--表单(下拉<select>、输入框<input>、文本域<textare>复选框<checkbox>和单选按钮<radio>)
html 里面的 role 本质上是增强语义性,当现有的HTML标签不能充分表达语义性的时候,就可以借助role来说明.通常这种情况出现在一些自定义的组件上,这样可增强组件的可访问性.可用性和可交互性 ...
随机推荐
- 初步认知java的方法
1.正确区分函数和方法: 面向对象的语言叫做方法,面向过程的语言叫做函数,两者的意义是一样的,只是叫法不同.java是面向对象的语言,所以用方法. 2.方法的定义: 就是有名字的代码段 3.方法的目的 ...
- 解决嵌入式linux系统下iconv库的移植问题
一.解决问题 在arm开发板上使用framebuff,在汉字显示时,因为只有gb2312的16*16的汉字字库,而ubuntu16.04默认 的编码方式时utf-8,因此需要进行转码(ut ...
- ie6对hover兼容性问题的解决:
ie6对hover兼容性问题的解决: 1,在body里添加以下样式: behavior:url(../scripts/csshover.htc); csshover.htc可直接在网上下载 2,js解 ...
- 使用TCP的HelloServer
HelloServer是一个在1234端口监听的服务端程序,它接受客户送来的数据,并且把这些数据解释为响应的ASCII字符,再对客户做出类似“Hello,...!"这样的响应.以下是Hell ...
- pwnable echo1
最近忙的好久没有更新了,有空把之前拿来练手的CTF pwn题逐渐整理一下放出来 题目是 linux 64位程序 ,流程很简单,大致思路就是先把一个跳转的机器指令写进name的地址,然后溢出覆盖eip, ...
- python中的input,print
此用例在python3.3.5中测试通过: 输入:在python中输入是使用input,下面示例代码表示把输入的值存入变量s中,并输入s 在这里提醒一下:使用input获取的值都是string类型
- visual studio 的Error List 显示乱码
复制到右键菜单如下: Severity Code Description Project File LineError 閿欒: 绋嬪簭鍖卌om.baidu.lbsapi.auth涓嶅瓨鍦? com. ...
- DEX 方法超过64K限制和gradle编译OOM问题解决
如果你是一个android开发者,你至少听说过的Dalvik的蛋疼的64K方法限制.概括地说,在一个DEX文件,你可以调用很多的方法,但你只能调用它们最前面的65,536个 ,因为这是在方法调用集合中 ...
- 压力测试报出503错误---ASP.NET支持大并发的相关配置
项目反馈报出503错误,需要收集性能数据如下: 1.Windows性能监视器,该应用程序池进程的线程和处理队列 2.问题重现时的进程dump 这是请求到达IIS后遇到的第一个队列,HTTP.sys收到 ...
- windows7 阻止copyfile到windows目录的解决办法
一. windows7 x64,uac会阻止copyfile到c:/windows.提示拒绝访问. [会引起uac提示的3种情况: Administrator access token checks. ...