views:

114

answers:

3

Hi, I am currently defining few grids as following:

<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>

While the division works fine , the subtraction isn't yielding the output.

Ialso tried like following:

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

Still no result. Any suggestions plz.

Thanks, Subhen

**

Update

** Now In My XAML I tried implementing the IvalueConverter like :

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

Added the reference as

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

In side generic.cs I have coded as following:

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
    }

But getting the exception Unknown Element Height in the element RowDefination.

Updating Code @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>

Now , My implementing XAML file contains is as follows:

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

Now, I want to substract or divide the values depending on the height of custMediaElement.

+1  A: 

I think you have to use Converter for this purpose

Kishore Kumar
A: 

You have posed several good questions; however, we often get caught up in finding a solution while overlooking the original problem. Before attempting to answer your questions I would like to explorer you layout expectations.

Your provided code suggests that you have a custom control (customVideoControl) whose instance is a height of 300px. The ControlTemplate applied to this control has 4 rows, which have calculated heights based on the instance height. Based on these settings your 4 rows would have the following values:

Row 0: 240 Row 1: 20 Row 2: 60 Row 3: 50

These total to 370px, which is 70px larger than the control. This means that Row 3 would be completely hidden from view, and Row 2 would be clipped down to the top 40px. I assume that this is not your intention. If this is your intention, then the answers below will hopefully help you on your path. If your intention is to scale the row heights based on a ratio, then you can use star sizing. Your suggested ratio would use the following settings:

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

If you would still like to measure the height of the rows then there are a few corrections that you need to make.

  1. Mathematical operations cannot be performed within markup extensions (the curly braces). Your division approach may not be throwing a xaml parse exception, but I doubt that it is working correctly. A value converter is necessary to accomplish what you want.

  2. TemplateBinding is really just a light-weight version of a RelativeSource binding. Since TemplateBinding is light-weight it doesn't allow for Converters.

To get your expected behavior you need to use a Binding with a RelativeSource. Therefore the code you want looks something like this:

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

Where DivisionConverter is the key of a custom converter. The ConverterParameter in this example allows the developer to pass in a denominator, instead of having to create a separate converter for each number.

Here's an example of the custom DivisionConverter you will need to create:

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

If you wanted to incorporate both division and subtraction in the same Binding you would need to either create a special converter, or use a MultiBinding (which would also require you to create a special MultiBindingConverter).

Tony Borres
As this is a custom control , I am defining height as dependency property in my code . Updated the code again in my question.Also if you cant let me know why we are using ConverterParameter=15 , will help me a lot. Thanks
Subhen
I've updated the answer in response to your new code. I've also included an example DivisionConverter class and explained the ConverterParameter. Let me know if you still have questions.
Tony Borres
A: 

Instead of subtracting one-fifth, why don't you just multiply by .8?

Robert Rossney