Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何仅修改WPF控件的右(或左、上、下)值';谁的保证金财产?_Wpf_Xaml_Mvvm_Wpf Controls_Mvvm Light - Fatal编程技术网

如何仅修改WPF控件的右(或左、上、下)值';谁的保证金财产?

如何仅修改WPF控件的右(或左、上、下)值';谁的保证金财产?,wpf,xaml,mvvm,wpf-controls,mvvm-light,Wpf,Xaml,Mvvm,Wpf Controls,Mvvm Light,这很容易从代码隐藏中实现: var button = new Button(); var margin = button.Margin; margin.Right = 10; button.Margin = margin; 但是,在XAML中,我仅限于以下内容: <Button Margin="0,0,10,0" /> <Button ap:MoreProps.MarginRight="10" /> 问题是,现在我可能会通过将其他边距值(即左、上、下)设置为零来

这很容易从代码隐藏中实现:

var button = new Button();
var margin = button.Margin;
margin.Right = 10;
button.Margin = margin;
但是,在XAML中,我仅限于以下内容:

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

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

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

<Button MarginRight="10" />

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

例如,在应用程序中的某个位置定义以下类:

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 Margin="0,0,10,0" />
<Button ap:MoreProps.MarginRight="10" />



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






您的这部分有误:

var button = new Button();
button.Margin.Right = 10;
错误CS1612:无法修改的返回值 “System.Windows.FrameworkElement.Margin”,因为它不是变量

已不是有效代码,因为边距返回,因此是值类型。因为它不是从DependencyObject派生的,所以很多数据绑定技巧也不起作用


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

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

您可以将边距数据绑定到MVVM中的属性(字符串)。在MVVM中,您只需跟踪各个属性(顶部、右侧、底部、右侧)


您可以使用:或

@DOW中的转换器,以确保您对代码隐藏部分的了解是正确的。我的打字错误。我更新了我的问题,以反映我的实际意思。但是,数据绑定将起作用,因为MarginRight属性是DependencyObject。因此,每当通过绑定更改属性值时,回调方法中的边距都会相应调整。@bugged87我对数据绑定的意思是原始问题,而不是附加的属性答案。当然,数据绑定是可行的。但在厚度为的结构上,不能使用数据绑定,除非它是源。简言之,我不是在说MarginRight,而是在说Margin.Right。当您覆盖现有的
厚度时,末尾的XAML与
Margin=“0,0,10,0”
是一样的。@H.B.谢谢,我应该测试最后一部分。你说得对。整个边距将被重新分配,任何未指定的值都将返回默认值。我已经编辑了标记该部分的答案。不幸的是,这不起作用,在设置附加属性时,边距尚未设置,因此,我修改默认的0边距,而不是XAMLData绑定到视图模型中的属性中指定的边距,这意味着视图模型必须维护特定于UI设计的值。这打破了MVVM模式。我完全同意你。。。我们在“UI”特定功能之间的界限在哪里,比如根据状态为行着色。如果涉及到“逻辑”,并且代码依赖于“其他”属性,如服务结果和/或属性,那么MVVM就是。。。或者,您可以随时附加行为。您对重构代码有什么建议吗?如果XAML设计器缺少必需的功能,那么代码隐藏似乎是添加额外功能的好地方。请记住,在单个位置定义和维护的附加属性实际上与在每个XAML文件的代码隐藏中编写代码不同。我想这也取决于你在代码背后做了什么。如果您正在修改数据上下文,那么是的,您可能会导致MVVM模式出现问题。不过,如果你只是修改UI组件,那可能没问题。这一点我一直有一个问题。。。代码隐藏是一个带有XAML代码的分部类。。。它与XAML处于同一级别。如果它可以用来做与UI相关的活动,那么它和在XAML中做没有什么不同。