标签:closed on() bottom lte image rgs protected contain csharp
实现思路:
1.继承ComboBox
2.重写ComboBox的模板,把列表控件替换成树形控件
3.重写SelectedItem, SelectedValue,DisplayMemberPath,SelectedValuePath
效果截图:
XAML代码
cs代码
///
/// TreeSelect.xaml 的交互逻辑
///
[TemplatePart(Name = "PART_TreeView", Type = typeof(TreeView))]
public partial class TreeSelect : ComboBox
{
public bool IsMulti
{
get { return (bool)GetValue(IsMultiProperty); }
set { SetValue(IsMultiProperty, value); }
}
public static readonly DependencyProperty IsMultiProperty =
DependencyProperty.Register("IsMulti", typeof(bool), typeof(TreeSelect), new PropertyMetadata(false));
public new string DisplayMemberPath
{
get { return (string)GetValue(DisplayMemberPathProperty); }
set { SetValue(DisplayMemberPathProperty, value); }
}
public new static readonly DependencyProperty DisplayMemberPathProperty =
DependencyProperty.Register("DisplayMemberPath", typeof(string), typeof(TreeSelect));
public new string SelectedValuePath
{
get { return (string)GetValue(SelectedValuePathProperty); }
set { SetValue(SelectedValuePathProperty, value); }
}
public new static readonly DependencyProperty SelectedValuePathProperty =
DependencyProperty.Register("SelectedValuePath", typeof(string), typeof(TreeSelect));
///
/// Selected item of the TreeView
///
public new object SelectedItem
{
get { return (object)GetValue(SelectedItemProperty); }
set { SetValue(SelectedItemProperty, value); }
}
public new static readonly DependencyProperty SelectedItemProperty =
DependencyProperty.Register("SelectedItem", typeof(object), typeof(TreeSelect), new PropertyMetadata(null, new PropertyChangedCallback(OnSelectedItemChanged)));
private static void OnSelectedItemChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
((TreeSelect)sender).UpdateSelectedItem();
}
public new object SelectedValue
{
get { return (object)GetValue(SelectedValueProperty); }
set { SetValue(SelectedValueProperty, value); }
}
public new static readonly DependencyProperty SelectedValueProperty =
DependencyProperty.Register("SelectedValue", typeof(object), typeof(TreeSelect), new PropertyMetadata(null));
public new string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(TreeSelect));
///
/// Gets or sets text separator.
///
public string TextSeparator
{
get { return (string)GetValue(TextSeparatorProperty); }
set { SetValue(TextSeparatorProperty, value); }
}
public static readonly DependencyProperty TextSeparatorProperty =
DependencyProperty.Register("TextSeparator", typeof(string), typeof(TreeSelect), new PropertyMetadata(","));
///
/// Gets or sets max text length.
///
public int? MaxTextLength
{
get { return (int?)GetValue(MaxTextLengthProperty); }
set { SetValue(MaxTextLengthProperty, value); }
}
public static readonly DependencyProperty MaxTextLengthProperty =
DependencyProperty.Register("MaxTextLength", typeof(int?), typeof(TreeSelect));
///
/// Gets or sets text filler when text length exceeded.
///
public string ExceededTextFiller
{
get { return (string)GetValue(ExceededTextFillerProperty); }
set { SetValue(ExceededTextFillerProperty, value); }
}
public static readonly DependencyProperty ExceededTextFillerProperty =
DependencyProperty.Register("ExceededTextFiller", typeof(string), typeof(TreeSelect), new PropertyMetadata("..."));
static TreeSelect()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(TreeSelect), new FrameworkPropertyMetadata(typeof(TreeSelect)));
}
public TreeSelect()
{
Loaded -= TreeSelect_Loaded;
Loaded += TreeSelect_Loaded;
SizeChanged -= TreeSelect_SizeChanged;
SizeChanged += TreeSelect_SizeChanged;
}
private ExtendedTreeView _treeView;
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
this._treeView = Template.FindName("PART_TreeView", this) as ExtendedTreeView;
if (this._treeView != null)
{
//this._treeView.SelectedItemChanged += _TreeView_SelectedItemChanged;
_treeView.OnHierarchyMouseUp += new MouseEventHandler(OnTreeViewHierarchyMouseUp);
_treeView.AddHandler(System.Windows.Controls.TreeViewItem.SelectedEvent, new System.Windows.RoutedEventHandler(treeview_Selected));
}
}
//protected override void OnDropDownClosed(EventArgs e)
//{
// base.OnDropDownClosed(e);
// this.SelectedItem = _treeView.SelectedItem;
// this.UpdateText();
//}
//protected override void OnDropDownOpened(EventArgs e)
//{
// base.OnDropDownOpened(e);
// this.UpdateText();
//}
///
/// Handles clicks on any item in the tree view
///
private void OnTreeViewHierarchyMouseUp(object sender, MouseEventArgs e)
{
//This line isn‘t obligatory because it is executed in the OnDropDownClosed method, but be it so
this.SelectedItem = _treeView.SelectedItem;
this.UpdateText();
base.SelectedItem = this.SelectedItem;
this.IsDropDownOpen = false;
}
private void treeview_Selected(object sender, RoutedEventArgs e)
{
TreeViewItem item = (e.OriginalSource as TreeViewItem);
if (item != null)
{
item.BringIntoView();
}
}
protected override bool IsItemItsOwnContainerOverride(object item)
{
if (item is ComboBoxItem)
return true;
else
return false;
}
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
var uie = element as FrameworkElement;
if (!(item is ComboBoxItem))
{
var textBinding = new Binding(DisplayMemberPath);
textBinding.Source = item;
uie.SetBinding(ContentPresenter.ContentProperty, textBinding);
}
base.PrepareContainerForItemOverride(element, item);
}
private void TreeSelect_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (!IsLoaded)
return;
UpdateText();
}
private void TreeSelect_Loaded(object sender, RoutedEventArgs e)
{
UpdateText();
}
private void UpdateSelectedItem()
{
UpdateText();
base.SelectedItem = this.SelectedItem;
if (this.SelectedItem == null || string.IsNullOrEmpty(this.SelectedValuePath))
{
SelectedValue = null;
}
else
{
SelectedValue = this.SelectedItem.GetType().GetProperty(SelectedValuePath).GetValue(this.SelectedItem, null);
}
}
private void _TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgsobject> e)
{
if (!IsLoaded)
return;
UpdateText();
base.SelectedItem = this.SelectedItem;
}
private void UpdateText()
{
if (IsMulti == false)
{
Text = GenerateText(SelectedItem);
}
else
{
Text = GenerateText();
}
}
public string GenerateText(object selectedItem)
{
var text = "";
if (selectedItem == null)
{
text = "";
}
else if (selectedItem is ComboBoxItem)
{
var msi = selectedItem as ComboBoxItem;
text += msi.Content.ToString();
}
else
{
if (!string.IsNullOrEmpty(DisplayMemberPath) && selectedItem.GetType().GetProperty(DisplayMemberPath) != null)
text += selectedItem.GetType().GetProperty(DisplayMemberPath).GetValue(selectedItem, null).ToString();
else
text += selectedItem.ToString();
if (selectedItem.GetType().GetProperty("IsSelected") != null)
{
selectedItem.GetType().GetProperty("IsSelected").SetValue(selectedItem, true);
}
}
return text;
}
public string GenerateText()
{
var text = "";
var isFirst = true;
foreach (var item in Items)
{
if (!isFirst)
text += TextSeparator;
else
isFirst = false;
if (item is ComboBoxItem)
{
var msi = item as ComboBoxItem;
text += msi.Content.ToString();
}
else
{
if (item.GetType().GetProperty("IsSelected") != null && item.GetType().GetProperty("IsSelected").GetValue(item, null).ToString() == "true")
{
if (!string.IsNullOrEmpty(DisplayMemberPath) && item.GetType().GetProperty(DisplayMemberPath) != null)
text += item.GetType().GetProperty(DisplayMemberPath).GetValue(item, null).ToString();
else
text += item.ToString();
}
}
if (MaxTextLength == null)
{
if (!ValidateStringWidth(text + ExceededTextFiller))
{
if (text.Length == 0)
return null;
text = text.Remove(text.Length - 1);
while (!ValidateStringWidth(text + ExceededTextFiller))
{
if (text.Length == 0)
return null;
text = text.Remove(text.Length - 1);
}
return text + ExceededTextFiller;
}
}
else if (text.Length >= MaxTextLength)
{
return text.Cut((int)MaxTextLength, ExceededTextFiller);
}
}
return text;
}
private bool ValidateStringWidth(string text)
{
var size = MeasureString(text);
if (size.Width > (ActualWidth - Padding.Left - Padding.Right - 30))
return false;
else
return true;
}
private Size MeasureString(string candidate)
{
var formattedText = new FormattedText(candidate, System.Globalization.CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface(FontFamily, FontStyle, FontWeight, FontStretch), FontSize, Brushes.Black, new NumberSubstitution(), TextFormattingMode.Display);
return new Size(formattedText.Width, formattedText.Height);
}
}
使用:
完成,这个还支持多选的,没有完全完成,待续。
Wpf实现TreeSelect
标签:closed on() bottom lte image rgs protected contain csharp
原文地址:https://www.cnblogs.com/akwkevin/p/14199966.html