我遇到一个情况,需要将一个控件的
宽度绑定到另一个控件的
高度的一部分上,但我认为没有一个方便的内置方式可以像这样分割绑定属性。最终,我编写了一个转换器,它会将绑定的值除以转换器参数来解决这个问题,而不是采用代码后台,我想分享一下,以防其他人也能节省一些时间。我在这里发布它,因为当我搜索是否有更清洁的方法时,这篇文章是第一个结果。
转换器类:
[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>
结果:
![Result](https://istack.dev59.com/kAXkk.webp)