如何仅修改WPF控件的Margin属性的右侧(或左侧,顶部,底部)值?

bug*_*d87 12 wpf xaml mvvm wpf-controls mvvm-light

从代码隐藏中很容易做到这一点:

var button = new Button();
var margin = button.Margin;
margin.Right = 10;
button.Margin = margin;
Run Code Online (Sandbox Code Playgroud)

但是,在XAML中,我仅限于以下内容:

<Button Margin="0,0,10,0" />
Run Code Online (Sandbox Code Playgroud)

这个问题是,现在我可能通过将其设置为零来覆盖其他边距值(即左边,上边,下边).

有没有办法让XAML像下面那样?

<Button MarginRight="10" />
Run Code Online (Sandbox Code Playgroud)

bug*_*d87 14

可以使用附属物.实际上,这正是附加属性的目的:访问父元素属性或向特定元素添加其他功能.

例如,在应用程序的某处定义以下类:

using System;
using System.Windows;
using System.Windows.Controls;

namespace YourApp.AttachedProperties
{
    public class MoreProps
    {
        public static readonly DependencyProperty MarginRightProperty = DependencyProperty.RegisterAttached(
            "MarginRight",
            typeof(string),
            typeof(MoreProps),
            new UIPropertyMetadata(OnMarginRightPropertyChanged));

        public static string GetMarginRight(FrameworkElement element)
        {
            return (string)element.GetValue(MarginRightProperty);
        }

        public static void SetMarginRight(FrameworkElement element, string value)
        {
            element.SetValue(MarginRightProperty, value);
        }

        private static void OnMarginRightPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            var element = obj as FrameworkElement;

            if (element != null)
            {
                int value;
                if (Int32.TryParse((string)args.NewValue, out value))
                {
                    var margin = element.Margin;
                    margin.Right = value;
                    element.Margin = margin;
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,在您的XAML中,您所要做的就是声明以下命名空间:

xmlns:ap="clr-namespace:YourApp.AttachedProperties"
Run Code Online (Sandbox Code Playgroud)

然后你可以编写如下的XAML:

<Button ap:MoreProps.MarginRight="10" />
Run Code Online (Sandbox Code Playgroud)



或者,您可以避免使用附加属性,而是编写一些稍微冗长的XAML,例如:

<Button>
    <Button.Margin>
        <Thickness Right="10" />
    </Button.Margin>
</Button>

  • 最后的XAML与`Margin ="0,0,10,0"相同,因为如果有的话,你会覆盖现有的`Thickness`. (4认同)
  • @HB谢谢,我应该已经测试了最后一部分。你是对的。整个边距将被重新分配,所有未指定的值将返回默认值。我已经编辑了答案以标记该部分。 (2认同)