我遇到了一种情况,我需要将控件的 width 绑定到另一个控件的 height 的一小部分,但我认为没有一个方便的内置控件-以这样划分绑定属性的方式。我最终制作了一个转换器,它将一个边界值除以转换器参数来解决这个问题,而无需求助于代码隐藏,并认为我会分享它,以防它有助于节省其他人一些时间。我在这里发布它是因为这篇文章是我在搜索是否有更清洁的方式时的第一个结果。
转换器类:
[ValueConversion(typeof(double), typeof(double))]
public class DoubleDivisionConverter : System.Windows.Data.IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if(value == null) { return 0.0; }
if(parameter == null) { return value; }
double param;
if(Double.TryParse(parameter.ToString(), out param))
{
if(param == 0) { return 0.0; }
return (double)value / param;
}
else
{
throw new ArgumentException("Could not parse converter parameter as double.");
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if(value == null) { return 0.0; }
if(parameter == null) { return value; }
double param;
if(Double.TryParse(parameter.ToString(), out param))
{
if(param == 0) { return 0.0; }
return (double)value * param;
}
else
{
throw new ArgumentException("Could not parse converter parameter as double.");
}
}
}
XAML:(UniformGrid Width 属性上使用的转换器)
<Window.Resources>
<converters:DoubleDivisionConverter x:Key="DoubleDivisionConverter"/>
</Window.Resources>
<Grid x:Name="sampleGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.Resources>
<Style TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="FontSize" Value="18"/>
<Setter Property="FontWeight" Value="Bold"/>
</Style>
</Grid.Resources>
<Border x:Name="rSample" Grid.Column="0" Grid.Row="0" Background="PaleVioletRed">
<TextBlock>
<TextBlock.Inlines>
<Run Text="{Binding ElementName=rSample, Path=ActualWidth, StringFormat={}{0:N1}px, Mode=OneWay}"/><Run Text=", "/><Run Text="{Binding ElementName=rSample, Path=ActualHeight, StringFormat={}{0:N1}px, Mode=OneWay}"/>
</TextBlock.Inlines>
</TextBlock>
</Border>
<!-- Set the UniformGrids width to 1/3 the height of the parent grid using the converter -->
<UniformGrid Grid.Column="1" Grid.Row="0" Columns="1"
Width="{Binding ElementName=sampleGrid, Path=ActualHeight, Converter={StaticResource DoubleDivisionConverter}, ConverterParameter=3, Mode=OneWay}">
<Border x:Name="gSample" Background="LightGreen">
<TextBlock>
<TextBlock.Inlines>
<Run Text="{Binding ElementName=gSample, Path=ActualWidth, StringFormat={}{0:N1}px, Mode=OneWay}"/><Run Text=", "/><Run Text="{Binding ElementName=gSample, Path=ActualHeight, StringFormat={}{0:N1}px, Mode=OneWay}"/>
</TextBlock.Inlines>
</TextBlock>
</Border>
<Border x:Name="ySample" Background="LightGoldenrodYellow">
<TextBlock>
<TextBlock.Inlines>
<Run Text="{Binding ElementName=ySample, Path=ActualWidth, StringFormat={}{0:N1}px, Mode=OneWay}"/><Run Text=", "/><Run Text="{Binding ElementName=ySample, Path=ActualHeight, StringFormat={}{0:N1}px, Mode=OneWay}"/>
</TextBlock.Inlines>
</TextBlock>
</Border>
<Border x:Name="bSample" Background="LightBlue">
<TextBlock>
<TextBlock.Inlines>
<Run Text="{Binding ElementName=bSample, Path=ActualWidth, StringFormat={}{0:N1}px, Mode=OneWay}"/><Run Text=", "/><Run Text="{Binding ElementName=bSample, Path=ActualHeight, StringFormat={}{0:N1}px, Mode=OneWay}"/>
</TextBlock.Inlines>
</TextBlock>
</Border>
</UniformGrid>
</Grid>
结果: