绑定到 ControlTemplate 中的转换

发布于 2024-08-04 20:12:54 字数 851 浏览 5 评论 0原文

我正在尝试在 Silverlight 中创建一个自定义控件,该控件可以动态缩放其 ControlTemplate 中的元素。 ControlTemplate 的第一次尝试看起来像这样:

<ControlTemplate TargetType="controls:ProgressBar">
   <Grid>
      <Rectangle x:Name="TrackPart" Fill="{TemplateBinding Background}" HorizontalAlignment="Left" />
      <Rectangle x:Name="ProgressPart" Fill="Blue" >
      <Rectangle.RenderTransform>
         <ScaleTransform ScaleX="{TemplateBinding Progress}" />
            </Rectangle.RenderTransform>
         </Rectangle> 
   </Grid>
</ControlTemplate>

但是, 此论坛帖子指出 TemplateBinding 仅适用于 FrameworkElements 的派生类。 ScaleTransform 不是 FrameworkElement。有解决办法吗?对于这种情况有什么最佳实践吗?

I'm trying to create a custom control in Silverlight that dynamically scales an element in it's ControlTemplate. First attempt of the ControlTemplate looks something like this:

<ControlTemplate TargetType="controls:ProgressBar">
   <Grid>
      <Rectangle x:Name="TrackPart" Fill="{TemplateBinding Background}" HorizontalAlignment="Left" />
      <Rectangle x:Name="ProgressPart" Fill="Blue" >
      <Rectangle.RenderTransform>
         <ScaleTransform ScaleX="{TemplateBinding Progress}" />
            </Rectangle.RenderTransform>
         </Rectangle> 
   </Grid>
</ControlTemplate>

However, this forum thread states that TemplateBinding only works on derivatives of FrameworkElements. ScaleTransform is not a FrameworkElement. Is there a work around for this? Any best practices for this sort of situation out there?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

凌乱心跳 2024-08-11 20:12:54

您可以绑定 RenderTransform 本身,而不是绑定 RenderTransform 的 ScaleX 和 ScaleY 属性。
问题是源是双精度值,您需要一个 Transform。因此,您需要能够将 double 转换为 ScaleTransform。您可以创建一个 IValueConverter 来执行此操作:

public class TransformConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is double)
        {
            double d = (double)value;
            return new ScaleTransform { ScaleY = d, ScaleX = d };
        }
        else
        {
            return new ScaleTransform();
        }
    }

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

您无法指定要在 TemplateBinding 中使用的 IValueConverter,因此您可以使用以relativesource 作为 TemplatedParent 的常规 Binding。像这样:

    <Rectangle x:Name="ProgressPart" Fill="Blue" 
           RenderTransform="{Binding Path=Progress, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource converter1}}" >

您需要将 IValueConverter 放置在 ControlTemplate 的根资源中,在 Binding 的范围内:

<ControlTemplate TargetType="controls:ProgressBar">
    <Grid>
        <Grid.Resources>
            <local:TransformConverter x:Key="converter1" />
        </Grid.Resources>

Rather than binding the ScaleX and ScaleY properties of the RenderTransform, you can bind the RenderTransform itself.
The problem is that the source is a double value, and you need a Transform. So you need to be able to convert a double to a ScaleTransform. You can create an IValueConverter to do that:

public class TransformConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is double)
        {
            double d = (double)value;
            return new ScaleTransform { ScaleY = d, ScaleX = d };
        }
        else
        {
            return new ScaleTransform();
        }
    }

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

You can't specify an IValueConverter to use in a TemplateBinding, so you can use a regular Binding with RelativeSource as TemplatedParent. Like this:

    <Rectangle x:Name="ProgressPart" Fill="Blue" 
           RenderTransform="{Binding Path=Progress, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource converter1}}" >

and you need to place the IValueConverter in the resources of ControlTemplate's root, in scope of the Binding:

<ControlTemplate TargetType="controls:ProgressBar">
    <Grid>
        <Grid.Resources>
            <local:TransformConverter x:Key="converter1" />
        </Grid.Resources>
咆哮 2024-08-11 20:12:54

假设您始终使用像矩形这样的简单项目,您可以将矩形的高度和宽度绑定到进度,然后使用绑定转换器相应地调整值

Assuming that you are always using simple items like a rectangle, you could bind the rectangle's height and width to the progress, and then use a binding converter to adjust the value accordingly

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文