ThicknessPropertyConverter,以便绑定Thickness的某几个属性

12 篇文章 0 订阅
4 篇文章 1 订阅

Margin的类型是Thickness,而Thickness的Top、Left等属性不是依赖项属性,不能单独绑定。网上有许多帖子询问如何绑定到Margin的某(几)个属性,如

(抱歉,我没有在中文圈里搜到相关的问题或介绍)

  1. Binding only part of the margin property of WPF control
  2. Binding just one Margin
  3. How to set a top margin only in XAML?

其大意就是

     <Slider Name="slider1" Grid.Row="0" Maximum="200" Value="100" />

     <Line Grid.Row="2" HorizontalAlignment="Left" Y2="1" Stretch="Fill" Stroke="Black" StrokeThickness="2"
           Margin.Left="{Binding Element=slider1 Value=Path}"/>

刚才说过,Margin.Left一句是行不通的,因为Left不是依赖项属性。

网上提供了一些办法,大多是专门针对某个属性,提供一个自定义转换器(ValueConverter),比如MarginTopConverter、MarginLeftConverter等;而不能通用。

为了解决这个不通用的缺陷,我写了一个ThicknessPropertyConverter。名称里有Thickness,因为Margin的类型是Thickness;名称里有Property,因为它可以绑定到Thickness的任意一个或几个属性。

下面我会贴上ThicknessPropertyConverter的用法、效果和代码,但请再等等。请仔细考虑下你是否真的必须绑定到Margin的某个属性。TranslateTransofrm可以满足你的要求吗?如下

     <Slider Name="slider1" Grid.Row="0" Maximum="200" Value="100" />

     <Line Grid.Row="2" HorizontalAlignment="Left" Y2="1" Stretch="Fill" Stroke="Black" StrokeThickness="2">
          <Line.RenderTransform>
              <TranslateTransform X="{Binding Path=Value, ElementName=slider}"/>
          </Line.RenderTransform>
     </Line>

如果你仍然需要绑定到Thickness的方法,请继续往下看。

用法

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:Data="clr-namespace:Gqqnbig.Windows.Data" Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Data:ThicknessPropertyConverter x:Key="thicknessSingleConverter"/>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <Slider Name="slider1" Grid.Row="0" Maximum="200" Value="100" />
        <Slider Name="slider2" Grid.Row="1" Maximum="200" Value="100" />

        <Line Grid.Row="2" HorizontalAlignment="Left" Y2="1" Stretch="Fill" Stroke="Black" StrokeThickness="2">
            <Line.Margin>
                <MultiBinding Converter="{StaticResource thicknessSingleConverter}" ConverterParameter="{}{0} {1} 0 0">
                    <Binding ElementName="slider1" Path="Value"/>
                    <Binding ElementName="slider2" Path="Value"/>
                </MultiBinding>
            </Line.Margin>
        </Line>
    </Grid>
</Window>

这里有两个滑块(slider)和一条垂直的黑线。第一个滑块控制黑线的Margin.Left,第二个滑块控制黑线的Margin.Top。

效果

代码

推荐文件名:ThicknessPropertyConverter.cs。本文件的代码,依照MIT许可证发布。


/*
本代码依照 MIT许可证 发布,关于该许可证的具体条款,可参考维基百科 http://zh.wikipedia.org/zh-cn/MIT%E8%A8%B1%E5%8F%AF%E8%AD%89

Copyright (c) 2013 爱让一切都对了(Gqqnbig) Gqqnb2005@gmail.com

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

namespace Gqqnbig.Windows.Data
{
    using System;
    using System.Globalization;
    using System.Windows;
    using System.Windows.Data;



    [ValueConversion(typeof(double), typeof(Thickness))]
    partial //partial令到你可以创建本类的另一个分部类,更改访问性,如改为public,而不用修改本文件。
        class ThicknessPropertyConverter : IValueConverter, IMultiValueConverter
    {
        private static readonly ThicknessConverter thicknessConverter = new ThicknessConverter();

        #region Implementation of IValueConverter

        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <param name="targetType"></param>
        /// <param name="parameter">带有{0}的格式化字符串,其他格式必须遵守ThicknessConverter的规定。</param>
        /// <param name="culture"></param>
        /// <returns></returns>
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            try
            {
                return thicknessConverter.ConvertFromString(string.Format(((string)parameter), value));
            }
            catch (InvalidCastException e)
            {
                throw new ArgumentException("parameter必须为字符串类型", e);
            }
            catch (FormatException e)
            {
                throw new ArgumentException("parameter必须符合格式化字符串的规定", e);
            }
            catch (NotSupportedException e)
            {
                throw new ArgumentException("string.Format(((string)parameter), value)必须产生有效的Thickness字符串表达式", e);
            }
        }

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

        #endregion

        #region Implementation of IMultiValueConverter

        /// <summary>
        /// 
        /// </summary>
        /// <param name="values"></param>
        /// <param name="targetType"></param>
        /// <param name="parameter">带有{0}到{3}的格式化字符串,其他格式必须遵守ThicknessConverter的规定。</param>
        /// <param name="culture"></param>
        /// <returns></returns>
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            if (values.Length > 4)
                throw new ArgumentException("ThicknessPropertyConverter最多从4个数据转换。", "values");

            try
            {
                return thicknessConverter.ConvertFromString(string.Format(((string)parameter), values));
            }
            catch (InvalidCastException e)
            {
                throw new ArgumentException("parameter必须为字符串类型", e);
            }
            catch (FormatException e)
            {
                throw new ArgumentException("parameter必须符合格式化字符串的规定", e);
            }
            catch (NotSupportedException e)
            {
                throw new ArgumentException("string.Format(((string)parameter), values)必须产生有效的Thickness字符串表达式", e);
            }
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}

所有代码下载:

CSDN

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值