WPF - 如何在用户点击复选框

时间:2018-05-31 08:19:16

标签: c# wpf events data-binding treeview

我在C#后面的代码中为ItemTemplate定义了TreeView。在ItemTemplate中,我有一个CheckBox和一个标签。 Tag和标签的TextCheckBox属性与数据绑定。

现在,只要用户点击CheckBox,我就想获得TreeViewItem对象。 我在CheckBox上使用了点击事件,但该事件未向我提供TreeViewItem的对象

如果有人可以解释它的解决方案,我将非常感激。

这是用C#编写的代码:

public static void FillTree()
{
    //assign treeview itemtemplate
    BIMExplorerUserControl.Instance.BimTreeView.ItemTemplate = GetHeaderTemplate();
    BIMExplorerUserControl.Instance.BimTreeView.ItemContainerGenerator.StatusChanged += new EventHandler(ItemContainerGenerator_StatusChanged);

    foreach (var category in ViewModel.Instance.DefaultExplorerView)
    {
        BIMExplorerUserControl.Instance.BimTreeView.Items.Add(category);

    }
}



public static DataTemplate GetHeaderTemplate()
{
    //create the data template
    DataTemplate dataTemplate = new DataTemplate();

    //create stack pane;
    FrameworkElementFactory stackPanel = new FrameworkElementFactory(typeof(StackPanel));
    stackPanel.Name = "parentStackpanel";
    stackPanel.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);

    // Create check box
    FrameworkElementFactory checkBox = new FrameworkElementFactory(typeof(CheckBox));
    checkBox.Name = "chk";
    checkBox.SetValue(CheckBox.NameProperty, "chk");
    checkBox.SetValue(CheckBox.TagProperty, new Binding());
    checkBox.SetValue(CheckBox.MarginProperty, new Thickness(2));
    checkBox.SetValue(CheckBox.TagProperty, new Binding() { Path = new PropertyPath("Name") });
    checkBox.AddHandler(CheckBox.ClickEvent, new RoutedEventHandler(CheckedEvent));
    stackPanel.AppendChild(checkBox);


    // create text
    FrameworkElementFactory label = new FrameworkElementFactory(typeof(TextBlock));
    label.SetBinding(TextBlock.TextProperty, new Binding() { Path = new PropertyPath("Name") });
    label.SetValue(TextBlock.ToolTipProperty, new Binding());

    stackPanel.AppendChild(label);


    //set the visual tree of the data template
    dataTemplate.VisualTree = stackPanel;

    return dataTemplate;

}


static void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)
{
    if (BIMExplorerUserControl.Instance.BimTreeView.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
    {
        foreach (var category in ViewModel.Instance.DefaultExplorerView)
        {
            TreeViewItem item = (TreeViewItem)BIMExplorerUserControl.Instance.BimTreeView.ItemContainerGenerator.ContainerFromItem(category);
            if (item == null) continue;
            item.IsExpanded = false;
            if (item.Items.Count == 0)
            {
                foreach (var element in category.Elements)
                {
                    item.Items.Add(element);
                }
            }
        }
    }

}

private static void CheckedEvent(object sender, RoutedEventArgs e)
{
    CheckBox checkbox = (CheckBox)e.Source;
    var name = checkbox.Tag.ToString();

}

enter image description here

1 个答案:

答案 0 :(得分:1)

您可以使用以下帮助程序方法在可视树中获取对CheckBox的父TreeViewItem的引用:

private static T FindParent<T>(DependencyObject dependencyObject) where T : DependencyObject
{
    var parent = VisualTreeHelper.GetParent(dependencyObject);

    if (parent == null) return null;

    var parentT = parent as T;
    return parentT ?? FindParent<T>(parent);
}

用法:

private static void CheckedEvent(object sender, RoutedEventArgs e)
{
    CheckBox checkbox = (CheckBox)sender;
    var name = checkbox.Tag.ToString();

    TreeViewItem tvi = FindParent<TreeViewItem>(checkbox);
    //...
}