Как изменить только правое (или левое, верхнее, нижнее) значение свойства Margin элемента управления WPF?

Это довольно легко сделать из кода:

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 ответов


можно использовать вложенное свойство. Фактически, это именно цель вложенных свойств: доступ к свойствам родительского элемента или добавление дополнительных функций к определенному элементу.

например, определите следующий класс где-нибудь в вашем приложении:

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>


хотя attatched свойство может работать. Я пытаюсь рефакторинг кода, так что вы не делаете изменения интерфейса в коде. Вы должны обрабатывать как можно больше пользовательского интерфейса внутри стороны дизайна файла. Я пытаюсь использовать codebehind файлов xaml как можно меньше, потому что это вызывает проблемы с MVVM.


вы можете привязать маржу к свойству (строке) в вашем MVVM. В вашем MVVM все, что вам нужно, это отслеживать отдельные свойства (вверху, справа, внизу, справа).

вы можете использовать преобразователи как в: как установить верхний предел только в XAML? или привязка только части свойства margin элемента управления WPF


вы ошибаетесь в этой части:

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

ошибка CS1612: не удается изменить возвращаемое значение - Система.Окна.Класс FrameworkElement.Маржа-потому что это не переменная

уже недопустимый код, потому что Margin возвращает struct и поэтому является типом значения. И поскольку он не является производным от DependencyObject, многие трюки с привязкой данных также не будут работать.

Я просто хотел дать правильное объяснение, в противном случае я бы сказал, что ваш первый ответ-это практически единственный способ.