简体   繁体   English

WPF 在运行应用程序之前使用附加属性

[英]WPF use attached property before running app

I have a WPF project using.Net Framework 4.7.2 (I have to use this version).我有一个使用.Net Framework 4.7.2 的 WPF 项目(我必须使用这个版本)。 The project uses a StackPanel that contains two Buttons .该项目使用包含两个ButtonsStackPanel Since there is no Spacing property for the StackPanel I made my own which adjusts the margin of every child element.由于StackPanel没有Spacing属性,我自己制作了它来调整每个子元素的边距。

Code for the DependencyProperty: DependencyProperty 的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;

namespace LobeTruTool.AttachedProperties
{
    public class MarginSetterProperty
    {
        public static readonly DependencyProperty ChildMarginProperty = DependencyProperty.RegisterAttached(
            "ChildMargin",
            typeof(Thickness), //thickness is the same as margin
            typeof(StackPanel),
            new UIPropertyMetadata(new Thickness(), MarginChangedCallback));

        public static void SetChildMargin(UIElement element, Thickness margin)
        {
            element.SetValue(ChildMarginProperty, margin);
            MarginChangedCallback(element, new DependencyPropertyChangedEventArgs());
        }

        public static Thickness GetChildMargin(UIElement element)
        {
            return (Thickness)element.GetValue(ChildMarginProperty);
        }

        private static void MarginChangedCallback(object sender, DependencyPropertyChangedEventArgs e)
        {
            StackPanel stackPanel = sender as StackPanel;

            if (stackPanel != null)
            {
                stackPanel.Loaded += StackPanel_Loaded;
            }
        }

        private static void StackPanel_Loaded(object sender, RoutedEventArgs e)
        {
            StackPanel stackPanel = sender as StackPanel;

            foreach (FrameworkElement child in stackPanel.Children)
            {
                if (child.Margin == default)
                {
                    child.Margin = GetChildMargin(stackPanel);
                }
            }
        }
    }
}

Code where it is used:使用它的代码:

<Window x:Class="LobeTruTool.View.Home"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:ap="clr-namespace:LobeTruTool.AttachedProperties"
        ...
        Title="Home" Height="450" Width="800">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Grid Grid.Column="1">
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center" ap:MarginSetterProperty.ChildMargin="10,10,10,10">
                <Button Height="40" Width="100"/>
                <Button Height="40" Width="100"/>
            </StackPanel>
        </Grid>
    </Grid>
</Window>

When running the app everything works as expected but it is impractical that I have to start my app to see what it's gonna look like.运行应用程序时,一切都按预期工作,但我必须启动我的应用程序才能看到它的外观是不切实际的。 So I was wondering if it was possible to adjust the margin before running the app.所以我想知道是否可以在运行应用程序之前调整边距。

Right now it looks like this: picture of current design现在它看起来像这样:当前设计的图片

When running the app it looks like this: picture of design when app is running运行应用程序时,它看起来像这样:应用程序运行时的设计图片

Solved thanks to a comment on the question.由于对该问题的评论而解决了。 All I had to do was changing typeof(StackPanel) to typeof(MarginSetterProperty) .我所要做的就是将typeof(StackPanel)更改为typeof(MarginSetterProperty)

Here is the whole code:这是整个代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;

namespace LobeTruTool.AttachedProperties
{
    public class MarginSetterProperty
    {
        public static readonly DependencyProperty ChildMarginProperty = DependencyProperty.RegisterAttached(
            "ChildMargin",
            typeof(Thickness), //thickness is the same as margin
            typeof(MarginSetterProperty),
            new UIPropertyMetadata(new Thickness(), MarginChangedCallback));

        public static void SetChildMargin(UIElement element, Thickness margin)
        {
            element.SetValue(ChildMarginProperty, margin);
        }

        public static Thickness GetChildMargin(UIElement element)
        {
            return (Thickness)element.GetValue(ChildMarginProperty);
        }

        private static void MarginChangedCallback(object sender, DependencyPropertyChangedEventArgs e)
        {
            StackPanel stackPanel = sender as StackPanel;

            if (stackPanel != null && stackPanel.Tag == default)
            {
                stackPanel.Loaded += StackPanel_Loaded;
                stackPanel.Tag = "loaded event subscribed";
            }
        }

        private static void StackPanel_Loaded(object sender, RoutedEventArgs e)
        {
            StackPanel stackPanel = (StackPanel)sender;

            foreach (FrameworkElement child in stackPanel.Children)
            {
                if (child.Margin == default)
                {
                    child.Margin = GetChildMargin(stackPanel);
                }
            }
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM