ThicknessPropertyConverter,以便綁定Thickness的某幾個屬性

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) [email protected]

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章