Margin的类型是Thickness,而Thickness的Top、Left等属性不是依赖项属性,不能单独绑定。网上有许多帖子询问如何绑定到Margin的某(几)个属性,如
(抱歉,我没有在中文圈里搜到相关的问题或介绍)
其大意就是
<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}"/>
网上提供了一些办法,大多是专门针对某个属性,提供一个自定义转换器(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>
推荐文件名: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