我的每个节点上都有一个经典按钮。我希望他们根据点击时所在的节点采取行动,但我找不到如何做到这一点。
我有 4 个数据库表材料/品牌/系列/产品。例如,当DeleteButton_Click运行时,如果它所在的节点是Brand节点,我该如何让它相应地工作?
<Button Width="18" Height="20" Click="DeleteButton_Click" Margin="2 0 0 0" Tag="{Binding DataContext}">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}}, Path=IsSelected}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
<Button.Content>
<Grid>
<TextBlock Text="Sil" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White"/>
</Grid>
</Button.Content>
</Button>
TreeNodeViewModel 代码。
namespace Bornander.UI.ViewModels
{ 公共静态类 ObservableCollectionExtensions { public static void AddRange(此 ObservableCollection 集合,IEnumerable 项) { foreach(项目中的变量项目) { 集合.添加(项目); } } }
public class TreeNodeViewModel : INotifyPropertyChanged
{
private readonly ObservableCollection<TreeNodeViewModel> children;
private readonly string name;
private static int nextId = 1;
public int Id { get; }
private bool expanded;
private bool match = true;
private bool isLastChild;
private bool isSelected;
private object item;
public TreeNodeViewModel(string name, IEnumerable<TreeNodeViewModel> children)
{
this.name = name;
this.children = new ObservableCollection<TreeNodeViewModel>();
this.children.AddRange(children);
Id = nextId++;
}
public TreeNodeViewModel(string name)
: this(name, Enumerable.Empty<TreeNodeViewModel>())
{
}
public void AddChildren(ObservableCollection<TreeNodeViewModel> children)
{
foreach (var child in children)
{
this.children.Add(child);
child.Parent = this;
}
}
public void AddChildren(params TreeNodeViewModel[] children)
{
foreach (var child in children)
{
this.children.Add(child);
child.Parent = this;
}
}
public override string ToString()
{
return name;
}
private bool IsCriteriaMatched(string criteria)
{
return String.IsNullOrEmpty(criteria) || name.Contains(criteria);
}
private void CheckChildren(string criteria, TreeNodeViewModel parent)
{
foreach (var child in parent.Children)
{
if (child.IsLeaf && !child.IsCriteriaMatched(criteria))
{
child.IsMatch = false;
}
CheckChildren(criteria, child);
}
}
public void ApplyCriteria(string criteria, Stack<TreeNodeViewModel> ancestors)
{
if (IsCriteriaMatched(criteria))
{
IsMatch = true;
foreach (var ancestor in ancestors)
{
ancestor.IsMatch = true;
ancestor.IsExpanded = !String.IsNullOrEmpty(criteria);
CheckChildren(criteria, ancestor);
}
IsExpanded = false;
}
else
{
IsMatch = false;
}
ancestors.Push(this);
foreach (var child in Children)
{
child.ApplyCriteria(criteria, ancestors);
}
ancestors.Pop();
}
public IEnumerable<TreeNodeViewModel> Children => children;
public string Name => name;
public bool IsExpanded
{
get => expanded;
set
{
if (value == expanded)
{
return;
}
expanded = value;
if (expanded)
{
foreach (var child in Children)
{
child.IsMatch = true;
}
}
}
}
public bool IsMatch
{
get => match;
set
{
if (value == match)
{
return;
}
match = value;
OnPropertyChanged(nameof(IsMatch));
}
}
public bool IsLastChild
{
get => isLastChild;
set
{
if (value == isLastChild)
{
return;
}
isLastChild = value;
OnPropertyChanged(nameof(IsLastChild));
}
}
public bool IsSelected
{
get => isSelected;
set
{
if (value == isSelected)
{
return;
}
isSelected = value;
OnPropertyChanged(nameof(IsSelected));
}
}
public object Item
{
get => item;
set
{
if (value == item)
{
return;
}
item = value;
OnPropertyChanged(nameof(Item));
}
}
public bool IsLeaf => !Children.Any();
public TreeNodeViewModel Parent { get; private set; }
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}