234 lines
8.5 KiB
C#
234 lines
8.5 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Specialized;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Data;
|
|
|
|
|
|
namespace WPFluent.Controls
|
|
{
|
|
[TemplatePart(Name = FilterTextBox, Type = typeof(System.Windows.Controls.TextBox))]
|
|
[TemplatePart(Name = "PART_EditableTextBox", Type = typeof(System.Windows.Controls.TextBox))]
|
|
public class ComboBoxEx : ComboBox
|
|
{
|
|
private const string FilterTextBox = "PART_FilterTextBox";
|
|
|
|
// Using a DependencyProperty as the backing store for FilterBoxPlaceholderText. This enables animation, styling, binding, etc...
|
|
public static readonly DependencyProperty FilterBoxPlaceholderTextProperty = DependencyProperty.Register(
|
|
nameof(FilterBoxPlaceholderText),
|
|
typeof(string),
|
|
typeof(ComboBoxEx),
|
|
new PropertyMetadata("输入关键字"));
|
|
|
|
public static readonly DependencyProperty HeaderPlacementProperty = DependencyProperty.Register(
|
|
nameof(HeaderPlacement),
|
|
typeof(Dock),
|
|
typeof(ComboBoxEx),
|
|
new PropertyMetadata(Dock.Top));
|
|
|
|
// Using a DependencyProperty as the backing store for Header. This enables animation, styling, binding, etc...
|
|
public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register(
|
|
nameof(Header),
|
|
typeof(string),
|
|
typeof(ComboBoxEx),
|
|
new PropertyMetadata(null));
|
|
|
|
public static readonly DependencyProperty PlaceholderTextProperty = DependencyProperty.Register(
|
|
nameof(PlaceholderText),
|
|
typeof(string),
|
|
typeof(ComboBoxEx),
|
|
new PropertyMetadata("请选择..."));
|
|
public static readonly DependencyProperty ShowFilterBoxProperty = DependencyProperty.Register(
|
|
nameof(ShowFilterBox),
|
|
typeof(bool),
|
|
typeof(ComboBoxEx),
|
|
new PropertyMetadata(true));
|
|
|
|
|
|
private System.Windows.Controls.TextBox filterTextBox;
|
|
private ICollectionView view;
|
|
|
|
static ComboBoxEx()
|
|
{
|
|
DefaultStyleKeyProperty.OverrideMetadata(
|
|
typeof(ComboBoxEx),
|
|
new FrameworkPropertyMetadata(typeof(ComboBoxEx)));
|
|
}
|
|
|
|
/// <summary>
|
|
/// 过滤搜索
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void PART_FilterTextBox_TextChanged(object sender, TextChangedEventArgs e)
|
|
{
|
|
if (filterTextBox == null)
|
|
return;
|
|
|
|
if (view != null)
|
|
{
|
|
view.Filter += (o) =>
|
|
{
|
|
if (o is string)
|
|
{
|
|
var value = o.ToString().ToLower();
|
|
return value.IndexOf(filterTextBox.Text.ToLower(), StringComparison.Ordinal) != -1;
|
|
}
|
|
else
|
|
{
|
|
var obj = GetPropertyValue(o, DisplayMemberPath);
|
|
//在xaml中写入Combobox时
|
|
if (obj is ComboBoxItem item)
|
|
{
|
|
obj = item.Content;
|
|
}
|
|
var value = Convert.ToString(obj).ToLower();
|
|
return value.IndexOf(filterTextBox.Text.ToLower(), StringComparison.Ordinal) != -1;
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取view
|
|
/// </summary>
|
|
/// <param name="e"></param>
|
|
/// <remarks>适用于在xaml中添加ComboBoxItem的情况</remarks>
|
|
protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
|
|
{
|
|
base.OnItemsChanged(e);
|
|
view = CollectionViewSource.GetDefaultView(Items);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取view
|
|
/// </summary>
|
|
/// <param name="oldValue"></param>
|
|
/// <param name="newValue"></param>
|
|
/// <remarks>适用于绑定ItemsSource</remarks>
|
|
protected override void OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue)
|
|
{
|
|
base.OnItemsSourceChanged(oldValue, newValue);
|
|
|
|
view = CollectionViewSource.GetDefaultView(ItemsSource);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取属性,若无法获取则返回源对象
|
|
/// </summary>
|
|
public static object GetPropertyValue(object obj, string path)
|
|
{
|
|
if (obj == null)
|
|
return string.Empty;
|
|
|
|
var result = obj;
|
|
if (!string.IsNullOrEmpty(path))
|
|
{
|
|
var property = obj.GetType().GetProperty(path);
|
|
if (property != null)
|
|
{
|
|
try
|
|
{
|
|
result = property.GetValue(obj, null);
|
|
return result;
|
|
}
|
|
catch
|
|
{
|
|
try
|
|
{
|
|
var type = obj.GetType();
|
|
var mInfo = type.GetMethod($"get_{path}");
|
|
if (mInfo != null)
|
|
{
|
|
result = mInfo.Invoke(obj, null);
|
|
return result;
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 应用样板
|
|
/// </summary>
|
|
public override void OnApplyTemplate()
|
|
{
|
|
base.OnApplyTemplate();
|
|
|
|
if (filterTextBox != null)
|
|
{
|
|
filterTextBox.TextChanged -= PART_FilterTextBox_TextChanged;
|
|
}
|
|
|
|
filterTextBox = GetTemplateChild(FilterTextBox) as System.Windows.Controls.TextBox;
|
|
if (filterTextBox != null)
|
|
{
|
|
filterTextBox.TextChanged += PART_FilterTextBox_TextChanged;
|
|
}
|
|
}
|
|
|
|
[Category("自定义"), Bindable(true, BindingDirection.OneWay), Description("搜索框水印")]
|
|
public string FilterBoxPlaceholderText
|
|
{
|
|
get { return (string)GetValue(FilterBoxPlaceholderTextProperty); }
|
|
set { SetValue(FilterBoxPlaceholderTextProperty, value); }
|
|
}
|
|
|
|
[Category("自定义"), Bindable(true, BindingDirection.TwoWay), Description("标题")]
|
|
public string Header
|
|
{
|
|
get { return (string)GetValue(HeaderProperty); }
|
|
set { SetValue(HeaderProperty, value); }
|
|
}
|
|
|
|
//public bool PlaceholderEnable
|
|
//{
|
|
// get { return (bool)GetValue(PlaceholderEnableProperty); }
|
|
// set { SetValue(PlaceholderEnableProperty, value); }
|
|
//}
|
|
|
|
//// Using a DependencyProperty as the backing store for PlaceholderEnable. This enables animation, styling, binding, etc...
|
|
//public static readonly DependencyProperty PlaceholderEnableProperty = DependencyProperty.Register(
|
|
// nameof(PlaceholderEnable),
|
|
// typeof(bool),
|
|
// typeof(ComboBoxEx),
|
|
// new PropertyMetadata(true)
|
|
//);
|
|
[Category("自定义"), Bindable(true, BindingDirection.OneWay), Description("标题位置")]
|
|
public Dock HeaderPlacement
|
|
{
|
|
get { return (Dock)GetValue(HeaderPlacementProperty); }
|
|
set { SetValue(HeaderPlacementProperty, value); }
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// <para>特性含义:属性面板(支持分组,支持数据绑定,支持属性提示)</para>
|
|
/// <para>[Category("自定义分组"),Bindable(true,BindingDirection.OneWay),Description("选择框水印")]</para>
|
|
/// </remarks>
|
|
[Category("自定义"), Bindable(true, BindingDirection.OneWay), Description("选择框水印")]
|
|
public string PlaceholderText
|
|
{
|
|
get { return (string)GetValue(PlaceholderTextProperty); }
|
|
set { SetValue(PlaceholderTextProperty, value); }
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取或者设置下拉列表过滤文本框的显示与隐藏
|
|
/// </summary>
|
|
[Category("自定义"), Bindable(true, BindingDirection.OneWay), Description("过滤框")]
|
|
public bool ShowFilterBox
|
|
{
|
|
get => (bool)GetValue(ShowFilterBoxProperty);
|
|
set { SetValue(ShowFilterBoxProperty, value); }
|
|
}
|
|
}
|
|
}
|