为窗口中的每个Button创建一个MouseEnter事件

时间:2014-08-07 23:44:54

标签: c# wpf xaml

我几个月前一直在处理一个应用程序,我的朋友和我想和其他朋友分享这个应用程序,我需要显示一些帮助以使应用程序更容易,因为它只是为我们两个人设计的

出现的想法是每次从按钮弹出悬停事件时在文本块上显示帮助。所以我们添加了一个textBlock。现在我们仍面临的问题是如何为主窗口中的每个按钮创建悬停事件,此窗口中有很多按钮,因此我们无法向XAML代码中的每个按钮添加事件。

我对此答案的期望是以编程方式将哈佛事件添加到主窗口中的所有按钮?

编辑:经过一些谷歌搜索和帮助,我可以做到以下几点:

foreach (UIElement btn in GeneralMenuGrid.Children)
        {
            if (btn is Button)
            {
                Button currentButton = (Button)btn;
                currentButton.Content = "test";
            }

        }

这只是一个测试,它允许GeneralMenuGrid控件中的所有按钮都有一个内容:test,现在问题是我在这个网格中有嵌套控件,我怎么能到达它们?

编辑:经过多年的眩目,我必须循环浏览窗口中的所有按钮:

public static void EnumVisuals(Visual argVisual, Window currentWindow)
    {
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(argVisual); i++)
        {
            Visual childVisual = (Visual) VisualTreeHelper.GetChild(argVisual, i);
            if (childVisual is Button)
            {
                var button = childVisual as Button;
                button.MouseEnter += AllButtonsOnMouseEnter;
            }


            EnumVisuals(childVisual, currentWindow);
        }
    }

现在在AllButtonsOnMouseEnter函数中,我无法访问按钮,我将其公开...我无法从此类访问它,如何使用事件参数发送窗口?< / p>

3 个答案:

答案 0 :(得分:2)

我已经创建了一个扩展方法,可以从这里进行改编:Find all controls in WPF Window by type

将此课程放在项目的某个位置:

public static class VisualTreeSearch
{
    /// <summary>
    /// Finds all elements of the specified type in the <see cref="System.Windows.DependencyObject"/>'s visual tree using a breadth-first search.
    /// </summary>
    /// <typeparam name="T">The type of element to search for.</typeparam>
    /// <param name="root">The object to search in.</param>
    /// <returns>A list of elements that match the criteria.</returns>
    public static IEnumerable<T> Find<T>(this DependencyObject root) where T : DependencyObject
    {
        return root.Find<T>(false, true);
    }

    /// <summary>
    /// Finds all elements of the specified type in the <see cref="System.Windows.DependencyObject"/>'s visual tree.
    /// </summary>
    /// <typeparam name="T">The type of element to search for.</typeparam>
    /// <param name="root">The object to search in.</param>
    /// <param name="depthFirst">True to do a depth-first search; false to do a breadth-first search</param>
    /// <param name="includeRoot">True to include the root element in the search; false to exclude it</param>
    /// <returns>A list of elements that match the criteria.</returns>
    public static IEnumerable<T> Find<T>(this DependencyObject root, bool depthFirst, bool includeRoot) where T : DependencyObject
    {
        if (includeRoot)
        {
            var depRoot = root as T;
            if (depRoot != null)
                yield return depRoot;
        }

        var searchObjects = new LinkedList<DependencyObject>();
        searchObjects.AddFirst(root);

        while (searchObjects.First != null)
        {
            var parent = searchObjects.First.Value;
            var count = VisualTreeHelper.GetChildrenCount(parent);
            var insertAfterNode = depthFirst ? searchObjects.First : searchObjects.Last;

            for (int i = 0; i < count; i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(parent, i);
                var depChild = child as T;
                if (depChild != null)
                    yield return depChild;
                insertAfterNode = searchObjects.AddAfter(insertAfterNode, child);
            }
            searchObjects.RemoveFirst();
        }
    }
}

要使用扩展方法,请在窗口类中编写以下内容(作为示例)。此代码循环遍历this的所有子孙,孙子等等(在这种情况下应该是您的窗口)并查找所有Button元素。

foreach (var button in this.Find<Button>())
{
    button.MouseEnter += button_MouseEnter;
}

...

private void button_MouseEnter(object sender, MouseEventArgs e)
{
    // Do stuff
}

答案 1 :(得分:2)

您写道,&#34;此窗口中有很多按钮,因此我们无法向XAML代码中的每个按钮添加事件。&#34;但您可以 - 只需添加适用于所有按钮的样式:

<Style TargetType="{x:Type Button}">
  <EventSetter Event="MouseEnter" Handler="Button_MouseEnter"/>
</Style>

我不知道您打算如何获取与每个按钮相关的帮助文本,但很容易将其存储在Button的标签中:

<Button Tag="Instantly move from one place to another.">
Teleport
</Button>

然后编写一个事件处理程序,显示TextBlock中的帮助:

private void Button_MouseEnter(object sender, MouseEventArgs e)
{
    Button button = sender as Button;
    textblock_that_shows_help.Text = button.Tag;
}

答案 2 :(得分:-2)

经过大量的谷歌搜索和聊天帮助......我终于做到了,也许其他人会感兴趣这就是我的进展:

我创建了一个静态递归函数,它将获取窗口中的所有按钮:

public static void EnumVisuals(Visual argVisual, Button toModifyButton)
    {
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(argVisual); i++)
        {
            Visual childVisual = (Visual) VisualTreeHelper.GetChild(argVisual, i);
            if (childVisual is Button)
            {
                var button = childVisual as Button;
                button.MouseEnter += (sender, eventArgs) =>
                {
                    toModifyButton.Content = "Get the Help text from database if you want";
                };
            }


            EnumVisuals(childVisual, toModifyButton);
        }
    }

为什么要发送按钮

我需要在一个按钮中编写帮助,我发现访问它的内容属性的唯一方法是通过此功能发送它,当然也将其公开。

希望你能发现这有用。