如何为模板元素创建事件?

发布于 2024-12-11 23:37:14 字数 325 浏览 0 评论 0原文

我有机会在 WPF 中为模板中的控件执行事件而不创建 UserControl 等吗? 例如:创建的窗口模板有自定义的“关闭(X)”按钮。每个窗口都有相同的操作。有机会让它发挥作用吗?给出 Click 事件会关闭窗口吗?

我的意思是这样使用它:

<Window style="{StaticResource MyWindowTemplate}">...</Window>

并且不创建 Window 的自定义类,因为我希望有机会将它用于 Windows 的每个类。

那么有机会这样做吗?或者有类似或更好的解决方案吗?

I there any chance in WPF to do a event for control in template not creating a UserControl or so on?
For example: created window template has custom "Close(X)" button. It has the same operation for every windows. It is any chance to make it working? Give Click event which will close the window?

I mean to use it like this:

<Window style="{StaticResource MyWindowTemplate}">...</Window>

And doesnt create custom class of Window because I want to have opportunity to use it to every classes of Windows.

So there is any chance to do it like this? Or any similar or better solution?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

ぽ尐不点ル 2024-12-18 23:37:14

我不认为 Template 可以实现某种行为。它们是为了外观和感觉,而不是行为。对于行为,我们附加了属性和行为,当附加到其有效的目标依赖对象时,它们的行为完全相同。

例如,在您的情况下,右上角的关闭按钮是一个困难的按钮,但窗口上的任何按钮都会关闭目标 UI,即在指定某些附加行为时关闭窗口本身。

 <Window x:Class="..."
         ...>
    <Grid>
        <Grid.RowDefinitions>
           <RowDefinition Height="*"/>
           <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <ContentControl ... />
        <Buton Width="100"
               Content="Close"
               local:CloseBehavior.IsCloseButton="True" />
   </Grid>
 </Window>

因此,在上面的示例中,任何配置有附加行为的按钮 local:CloseBehavior.IsCloseButton="True" 都会使该按钮单击以关闭其祖先窗口。

编辑:

CloseBehavior.IsCloseButton 类似于下面给出的内容。因此,在下面的代码中,当我们针对任何窗口上的任何按钮将 IsCloseButton 附加属性设置为 true 时,使用视觉和逻辑遍历,附加行为会搜索祖先窗口,然后将其关闭当点击时。

public static class CloseBehavior
{
    public static readonly DependencyProperty IsCloseButtonProperty
        = DependencyProperty.RegisterAttached(
            "IsCloseButton",
            typeof (bool),
            typeof (CloseBehavior),
            new PropertyMetadata(
               false,
               OnIsCloseButtonPropertyChanged));

    private static void OnIsCloseButtonPropertyChanged
        (DependencyObject depObj,
         DependencyPropertyChangedEventArgs e)
    {
        var buttonBase = depObj as ButtonBase;
        if (buttonBase != null && (bool)e.NewValue)
        {
            buttonBase.Click
                += (o, args) =>
                    {
                        var window
                            = GetVisualLogicalParent(
                                  buttonBase,
                                  typeof(Window)) as Window;

                        if (window != null)
                        {
                            window.Close();
                        }
                    };
        }
    }

    public static bool GetIsCloseButton(DependencyObject depObj)
    {
        return (bool)depObj.GetValue(IsCloseButtonProperty);
    }

    public static void SetIsCloseButton(
        DependencyObject depObj,
        bool value)
    {
        depObj.SetValue(IsCloseButtonProperty, value);
    }

    public static DependencyObject GetVisualLogicalParent(
       DependencyObject depObj,
       Type type)
    {
        if (depObj != null)
        {
            var parent = VisualTreeHelper.GetParent(depObj);
            if (parent == null)
            {
                parent = LogicalTreeHelper.GetParent(depObj);
            }
            if (parent != null)
            {
                if (type.IsInstanceOfType(parent))
                {
                    return parent;
                }
                else
                {
                    return GetVisualLogicalParent(parent, type);
                }
            }
        }

        return null;
    }
}

我希望这有帮助。

I dont think Template can achieve a behavior. They are for look and feel but not behavior. For behaviors we have attached properties and behaviors which when attached to their valid target dependency objects to behave all the same.

e.g. in your case the close button on the top right corner is a difficult one but any button on the window close a target UI i.e. Window itself when specified with some attached behavior.

 <Window x:Class="..."
         ...>
    <Grid>
        <Grid.RowDefinitions>
           <RowDefinition Height="*"/>
           <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <ContentControl ... />
        <Buton Width="100"
               Content="Close"
               local:CloseBehavior.IsCloseButton="True" />
   </Grid>
 </Window>

So in the example above any button that is configured with an attached behavior local:CloseBehavior.IsCloseButton="True" makes that button click to close its ancestor window.

EDIT:

CloseBehavior.IsCloseButton is something like given below. So in the code below when we set IsCloseButton attached property as true against any button on any window, using visual and logical traversal the attached behavior searches the ancestor window and then closes it when clicked.

public static class CloseBehavior
{
    public static readonly DependencyProperty IsCloseButtonProperty
        = DependencyProperty.RegisterAttached(
            "IsCloseButton",
            typeof (bool),
            typeof (CloseBehavior),
            new PropertyMetadata(
               false,
               OnIsCloseButtonPropertyChanged));

    private static void OnIsCloseButtonPropertyChanged
        (DependencyObject depObj,
         DependencyPropertyChangedEventArgs e)
    {
        var buttonBase = depObj as ButtonBase;
        if (buttonBase != null && (bool)e.NewValue)
        {
            buttonBase.Click
                += (o, args) =>
                    {
                        var window
                            = GetVisualLogicalParent(
                                  buttonBase,
                                  typeof(Window)) as Window;

                        if (window != null)
                        {
                            window.Close();
                        }
                    };
        }
    }

    public static bool GetIsCloseButton(DependencyObject depObj)
    {
        return (bool)depObj.GetValue(IsCloseButtonProperty);
    }

    public static void SetIsCloseButton(
        DependencyObject depObj,
        bool value)
    {
        depObj.SetValue(IsCloseButtonProperty, value);
    }

    public static DependencyObject GetVisualLogicalParent(
       DependencyObject depObj,
       Type type)
    {
        if (depObj != null)
        {
            var parent = VisualTreeHelper.GetParent(depObj);
            if (parent == null)
            {
                parent = LogicalTreeHelper.GetParent(depObj);
            }
            if (parent != null)
            {
                if (type.IsInstanceOfType(parent))
                {
                    return parent;
                }
                else
                {
                    return GetVisualLogicalParent(parent, type);
                }
            }
        }

        return null;
    }
}

I hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文