WPF - Как получить представление дерева, когда пользователь нажимает на флажок - PullRequest
0 голосов
/ 31 мая 2018

Я определил ItemTemplate для TreeView в коде C #.В этом ItemTemplate у меня есть CheckBox и метка, определенная в нем.Свойства Tag и Text метки CheckBox и метки связаны с данными.

Теперь я хотел бы получить объект TreeViewItem всякий раз, когда пользователь нажимает на CheckBox. Я использовал событие click для 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 голосов
/ 31 мая 2018

Вы можете использовать следующий вспомогательный метод, чтобы получить ссылку на родительский элемент 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);
    //...
}
...