实现一个这样的多选列表控件
选中的项通过控件事件触发将结果字符串(分隔符可设置)发出来。
因为我想让checkbox的IsChecked作为控件Item本身的属性,不希望这个属性由数据层干预。也就是说我绑定在控件ItemSource的数据就是string集合。
所以就不用修改ListBoxItem样式模板这种的方案了,我自定义CheckListItem继承ListBoxItem。
思路
思路很简单,实现也不难
1.写一个CheckListItem模块继承ListBoxItem,给它添加IsCheck的属性和CheckedChanged的事件。
2.写一个CheckList继承ListBox,添加SelectedText属性 代表所有选择的内容,和SplitChar属性,设置分隔符。还要有SelectedTextChanged事件,用来显示。
3.通过重写ListBox的GetContainerForItemOverride()方法 把新建的Item设为CheckListItem,然后在PrepareContainerForItemOverride()方法里将每一个CheckListItem的CheckedChanged事件都绑定好。
4.在绑定好的事件里更新SelectedText属性然后把它SelectedTextChanged传出去。
5.写样式,我暂时没有考虑样式统一问题,先BaseOn原样式。然后ListBoxItem的ControlTemplate重写
代码
CheckList.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
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 MaydayUI.View._List
{
public class CheckList :ListBox
{
#region 构造
static CheckList()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(CheckList), new FrameworkPropertyMetadata(typeof(CheckList)));
}
public CheckList()
{
}
#endregion
#region 属性
#region SelectedText
public string SelectedText
{
get { return (string)GetValue(SelectedTextProperty); }
set { SetValue(SelectedTextProperty, value); }
}
public static readonly DependencyProperty SelectedTextProperty =
DependencyProperty.Register("SelectedText", typeof(string), typeof(CheckList),
new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(OnSelectedTextPropertyChanged)));
private static void OnSelectedTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
CheckList obj = d as CheckList;
if (obj != null)
obj.OnSelectedTextChanged(e.NewValue.ToString());
}
private void OnSelectedTextChanged(string ext)
{
RoutedEventArgs args = new RoutedEventArgs(SelectedTextChangedEvent, ext);
RaiseEvent(args);
}
#endregion