17

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

var button = new Button();
var margin = button.Margin;
margin.Right = 10;
button.Margin = margin;

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

<Button Margin="0,0,10,0" />

问题在于,现在我可能通过将其他边距值(即左、上、下)设置为零来覆盖它们)。

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

<Button MarginRight="10" />
4

4 回答 4

17

可以使用附加属性。事实上,这正是附加属性的目的:访问父元素属性或为特定元素添加附加功能。

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

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;
                }
            }
        }
    }
}

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

xmlns:ap="clr-namespace:YourApp.AttachedProperties"

然后您可以编写 XAML,如下所示:

<Button ap:MoreProps.MarginRight="10" />



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

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

于 2012-09-28T00:42:32.850 回答
1

您可以将 Margin 数据绑定到 MVVM 中的属性(字符串)。在您的 MVVM 中,您只需要跟踪各个属性(上、右、下、右)。

您可以使用转换器,如:如何仅在 XAML 中设置上边距?仅绑定 WPF 控件的边距属性的一部分

于 2012-09-28T11:49:25.510 回答
1

尽管附加的属性可以工作。我会尝试重构您的代码,这样您就不会在后面的代码中进行 UI 更改。您应该在文件的设计端尽可能多地处理 UI。我尝试尽可能少地使用 xaml 文件的代码隐藏,因为它会导致 MVVM 出现问题。

于 2012-09-28T04:11:30.040 回答
0

这部分你错了:

var button = new Button();
button.Margin.Right = 10;

错误 CS1612:无法修改“System.Windows.FrameworkElement.Margin”的返回值,因为它不是变量

已经不是有效代码,因为 Margin 返回一个结构,因此是一个值类型。而且因为它不是从 DependencyObject 派生的,所以很多 DataBinding 技巧也不起作用。

我只是想给出一个适当的解释,否则我会说你的第一个答案几乎是唯一的方法。

于 2012-09-28T01:26:47.047 回答