我们可以在模板绑定时操纵(减去)属性的值吗?

时间:2010-04-28 10:49:43

标签: wpf silverlight xaml silverlight-3.0

我目前正在定义几个网格:

<Grid.RowDefinitions>
   <RowDefinition Height="{TemplateBinding Height-Height/5}"/>
   <RowDefinition Height="{TemplateBinding Height/15}"/>
   <RowDefinition Height="{TemplateBinding Height/20}"/>
  <RowDefinition Height="{TemplateBinding Height/6}"/>
 </Grid.RowDefinitions>

虽然除法正常,但减法不会产生输出。

我也尝试过如下:

<RowDefinition Height="{TemplateBinding Height-(Height/5)}"/>

仍然没有结果。任何建议PLZ。

谢谢, Subhen

**

更新

** 现在在我的XAML中,我尝试实现IvalueConverter,如:

<RowDefinition Height="{TemplateBinding Height, Converter={StaticResource heightConverter}}"/>

将参考添加为

<local:medieElementHeight x:Key="heightConverter"/>

在旁边的generic.cs中,我编码如下:

public class medieElementHeight : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            //customVideoControl objVdeoCntrl=new customVideoControl();
            double custoMediaElementHeight = (double)value;//objVdeoCntrl.customMediaPlayer.Height;

            double mediaElementHeight = custoMediaElementHeight - (custoMediaElementHeight / 5);
            return mediaElementHeight;
        }


        #region IValueConverter Members


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

        #endregion
    }

但是在元素RowDefination中获得异常未知元素高度。

更新代码 @Tony

<Style TargetType="local:customVideoControl">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:customVideoControl">
              <Grid>
                        <Grid.RowDefinitions>
                         <RowDefinition Height="{TemplateBinding Height-Height/5}"/>
                        <RowDefinition Height="{TemplateBinding Height/15}"/>
                       <RowDefinition Height="{TemplateBinding Height/20}"/>
                       <RowDefinition Height="{TemplateBinding Height/6}"/>
     </Grid.RowDefinitions>
                      <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="2*"/>
                          <ColumnDefinition Width="2*"/>
                          <ColumnDefinition Width="2*"/>
                      </Grid.ColumnDefinitions>
                    <MediaElement x:Name="customMediaPlayer" 
                                   Source="{TemplateBinding CustomMediaSource}"
                                   HorizontalAlignment="Center"
                                   VerticalAlignment="Center"
                                   Height="{TemplateBinding Height}"
                                   Width="{TemplateBinding Width}"
                                  Grid.Row="0" Grid.ColumnSpan="3"
                                  />
                   </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

现在,我实现的XAML文件包含如下:

<customMediaElement:customVideoControl x:Name="custMediaElement" Width="400" Height="300"  nextBtnEvent="custMediaElement_nextBtnEvent" prevBtnEvent="custMediaElement_prevBtnEvent" Visibility="Collapsed"/>

现在,我想根据custMediaElement的高度对值进行减法或除法。

3 个答案:

答案 0 :(得分:9)

你提出了几个好问题;但是,我们常常在忽略原始问题的同时找到解决方案。在尝试回答您的问题之前,我想探索您的布局预期。

您提供的代码表明您有一个自定义控件(customVideoControl),其实例的高度为300px。应用于此控件的ControlTemplate有4行,它们根据实例高度计算出高度。根据这些设置,您的4行将具有以下值:

第0行:240 第1:20行 第2行:60 第3行:50

这些总数达到370px,比对照大70px。这意味着第3行将完全隐藏在视图中,而第2行将被剪切到前40px。我认为这不是你的意图。如果这是您的意图,那么下面的答案将有助于您走上正轨。如果您打算根据比例缩放行高,则可以使用星形大小调整。您建议的比率将使用以下设置:

    <Grid.RowDefinitions>
        <RowDefinition Height="240*"/>
        <RowDefinition Height="20*"/>
        <RowDefinition Height="60*"/>
        <RowDefinition Height="50*"/>
    </Grid.RowDefinitions>

如果您仍想测量行的高度,则需要进行一些修正。

  1. 无法在标记扩展(花括号)中执行数学运算。你的除法方法可能不会抛出xaml解析异常,但我怀疑它是否正常工作。值转换器是完成您想要的所必需的。

  2. TemplateBinding实际上只是RelativeSource绑定的轻量级版本。由于TemplateBinding重量轻,因此不允许使用转换器。

  3. 要获得预期的行为,您需要使用与RelativeSource的绑定。因此,您想要的代码如下所示:

    <RowDefinition Height="{Binding Path=Height, 
                                RelativeSource={RelativeSource TemplatedParent}, 
                                Converter={StaticResource DivisionConverter}, 
                                ConverterParameter=15}"
                           />
    

    其中DivisionConverter是自定义转换器的关键。此示例中的ConverterParameter允许开发人员传入分母,而不必为每个数字创建单独的转换器。

    以下是您需要创建的自定义DivisionConverter的示例:

    public class DivisionConverter : IValueConverter
    {
        #region IValueConverter Members
    
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            // Default to 0. You may want to handle divide by zero 
            // and other issues differently than this.
            double result = 0;
    
            // Not the best code ever, but you get the idea.
            if (value != null && parameter != null)
            {
                try
                {
                    double numerator = (double)value;
                    double denominator = double.Parse(parameter.ToString());
    
                    if (denominator != 0)
                    {
                        result = numerator / denominator;
                    }
                    else
                    {
                        // TODO: Handle divide by zero senario.
                    }
                }
                catch (Exception e)
                {
                    // TODO: Handle casting exceptions.
                }
            }
    
            return result;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    
        #endregion
    

    如果你想在同一个Binding中加入除法和减法,你需要创建一个特殊的转换器,或者使用MultiBinding(这也需要你创建一个特殊的MultiBindingConverter)。

答案 1 :(得分:2)

我认为你必须为此目的使用转换器

答案 2 :(得分:2)

而不是减去五分之一,你为什么不乘以.8?