控制边距属性取决于 wpf 中的另一个控制边距属性

Posted

技术标签:

【中文标题】控制边距属性取决于 wpf 中的另一个控制边距属性【英文标题】:control margin properties depending on another control margin properties in wpf 【发布时间】:2014-10-07 01:11:25 【问题描述】:

我试图以这种方式在我的 wpf 应用程序的网格中显示两个画布控件。 second_canvas.margin.left 将与 first_canvas.margin.right 相同。 但它不能完成,因为 margin 属性不能用作变量。 所以我尝试了“厚度”。但我无法将 first_canvas.margin.right 转换为 thickness 变量,因为它是 double 类型。那么有什么解决方法吗?

【问题讨论】:

解决什么问题? @ethicallogics 您不能绑定到 Thickness 实例的属性,因为它们不是依赖属性。顺便说一句,Thickness 是一个值类型,所以它甚至不可能定义 DP。我再次猜想这是一种设计选择,它的缺点只有在有人使用 API 来做不平凡的事情时才会显现出来。 【参考方案1】:

我就是这样实现的……

int right = system.convert.ToInt32(first_canvas.margin.right)
second_canvas.margin = new thickness(left = right)

【讨论】:

【参考方案2】:

您可以编写一个专用的值转换器:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Windows;
using System.Windows.Data;

namespace WpfMagic

    class EditableMarginConverter : IValueConverter
    
        private double GetMarginPartValue(Thickness margin, string defaultValue, IDictionary<string, string> instructions)
        
            string sourceValue;
            string value = instructions.TryGetValue(defaultValue, out sourceValue) ? sourceValue : defaultValue;

            double numericalValue;
            if (double.TryParse(value, out numericalValue))
            
                return numericalValue;
            

            return value == "left" ? margin.Left :
                   value == "top" ? margin.Top :
                   value == "right" ? margin.Right :
                   margin.Bottom;
        

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        
            Thickness inputMargin = (Thickness)value;

            IDictionary<string, string> instructions = (parameter as string).Split()
                                                                            .Select(s => s.Split('='))
                                                                            .ToDictionary(t => t[0].ToLowerInvariant(), t => t[1].ToLowerInvariant());            

            Thickness outputMargin = new Thickness
            
                Left = GetMarginPartValue(inputMargin, "left", instructions),
                Top = GetMarginPartValue(inputMargin, "top", instructions),
                Right = GetMarginPartValue(inputMargin, "right", instructions),
                Bottom = GetMarginPartValue(inputMargin, "bottom", instructions)
            ;

            return outputMargin;
        

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        
            throw new NotImplementedException();
        
    

你会这样使用它:

<StackPanel xmlns:local="clr-namespace:WpfMagic" Orientation="Horizontal">
    <StackPanel.Resources>
        <local:EditableMarginConverter x:Key="marginConverter"></local:EditableMarginConverter>
    </StackPanel.Resources>
    <Canvas x:Name="first_canvas"
            Width="100"
            Height="100"
            Margin="0 0 10 0"
            Background="Red">
    </Canvas>
    <Canvas x:Name="second_canvas"
            Width="100"
            Height="100"
            Background="Green"
            Margin="Binding Margin,
                                ElementName=first_canvas,
                                Converter=StaticResource marginConverter,
                                ConverterParameter='Left=Right Right=0'">
    </Canvas>
</StackPanel>

这是一种可重复使用的方法,但如果它是一次性的,您可能应该使用一些程序管道,除非您是教条主义的并且想要拥有完美的 XAML。

【讨论】:

以上是关于控制边距属性取决于 wpf 中的另一个控制边距属性的主要内容,如果未能解决你的问题,请参考以下文章

WPF 边距厚度

盒模型基本概念

改变盒子模型外边距的是

运行时的WPF窗口边距不起作用

【css】内边距padding的属性和使用方法

CSS设置元素内边距(padding)外边距(margin)