2

I have a Grid that holds segments such as:

--
  ---
      -----------
                 ---
                    -------------------

Each segment's visual length is dependant upon the total length, and its position depends upon the end of the previous segment.

I have a MultiBinding to achieve this, that calculates Width of 3 ColumnDefinition.

I first thought I'd calculate the entire ColumnDefinitions so that each item is placed correctly, but as it happens, the compiler doesn't allow me to bind Grid.ColumnDefinitions, i.e you can't do this:

<Grid.ColumnDefinitions>
     <MultiBinding Converter="{StaticResource yourConverter}">
            <Binding Path=firstValueForCalculus />
            <Binding Path=secondValueForCalculus />
            ...   
     </MultiBinding>
</Grid.ColumnDefinitions>

So now, I'm thinking my only option is to make 3 IMultiValueConverters, bind each of the 3 ColumnDefinition.Width to their respective converter, and calculate everything... but that sounds very nasty and my "Oh-My-God-You're-Going-Down" alarm rang.

Any idea to do this elegantly?

Thanks!

EDIT: Yurek's code a bit modified : (Is that what you meant? or did I destroy it? :p)

public class GridHelper
    {
        public static readonly DependencyProperty ColumnDefinitionsProperty =
            DependencyProperty.RegisterAttached("ColumnDefinitions", typeof(ColumnDefinitionCollection), typeof(GridHelper),
            new FrameworkPropertyMetadata(null, new PropertyChangedCallback(
            (sender, e) => 
            {
                var element = sender as Grid;
                if (element != null)
                {
                    element.ColumnDefinitions.Clear();
                    foreach (ColumnDefinition col in (IEnumerable<ColumnDefinition>)e.NewValue)
                    {
                        element.ColumnDefinitions.Add(col);
                    }
                    //element.ColumnDefinitions.AddRange((IEnumerable<ColumnDefinition>)e.NewValue);
                }
            })));


        public static IEnumerable<ColumnDefinition> GetColumnDefinitions(Grid element)
        {
            return (IEnumerable<ColumnDefinition>)element.GetValue(ColumnDefinitionsProperty);
        }

        public static void SetColumnDefinitions(Grid element, IEnumerable<ColumnDefinition> columnDefinitions)
        {
            element.SetValue(ColumnDefinitionsProperty, columnDefinitions);
        }
    }
4

2 回答 2

4

You can't set ColumnDefinitions using binding because it is read only. But there is an elegant solution - to use attched dependency property.

public class GridHelper
    {
        public static readonly DependencyProperty ColumnDefinitionsProperty =
            DependencyProperty.RegisterAttached("ColumnDefinitions", typeof(ColumnDefinitionCollection), typeof(GridHelper),
            new FrameworkPropertyMetadata(null,
            (sender, e) =>
            {
                var element = sender as Grid;
                if(element != null)
                {
                     element.ColumnDefinitions.Clear();
                     element.ColumnDefinitions.AddRange((IEnumerable<ColumnDefinition>)e.NewValue);
                }
            }));

        public static IEnumerable<ColumnDefinition> GetColumnDefinitions(Grid element)
        {
            return (IEnumerable<ColumnDefinition>)element.GetValue(ColumnDefinitionsProperty);
        }

        public static void SetColumnDefinitions(Grid element, IEnumerable<ColumnDefinition> columnDefinitions)
        {
            element.SetValue(ColumnDefinitionsProperty, columnDefinitions);
        }
    }

Now you can use binding for column definitions creation:

<Grid>
     <local:GridHelper.ColumnDefinitions>
        <MultiBinding Converter="{StaticResource yourConverter}">
            <Binding Path=firstValueForCalculus />
            <Binding Path=secondValueForCalculus />
            ...   
        </MultiBinding>
     </local:GridHelper.ColumnDefinitions>
</Grid>
于 2011-08-08T15:05:03.920 回答
0

If I understand correctly, your audio file can be split in several parts, so an array.

I would create a collection of ColumnDefinition, each one having a width function of the audio part. Then the collection can be assigned to the Grid's ColumnDefinitions property.

EDIT: I forgot that the Grid property is read-only. So, you may add/remove the items runtime.

于 2011-08-08T15:05:53.367 回答