如何在WPF中设置Grid ColumnDefinitions的样式

时间:2022-12-29 13:13:06

I want to know how can I style a Grid so that I don't need to specify the

我想知道如何设置网格样式,以便我不需要指定

<Grid.ColumnDefinitions>
   <ColumnDefinition Width="auto" SharedSizeGroup="SG1"/>
   <ColumnDefinition Width="auto" SharedSizeGroup="SG2"/>
</Grid.ColumnDefinitions>

every time?

每次?

Thank you very much!

非常感谢你!

ps: I did try to search on Google first. But I couldn't find any answer. Anyone who find the answer from google could you please tell me what keyword do you use to search? Sometimes I find it hard to determine what keyword use to search.

ps:我确实尝试先在Google上搜索。但我找不到任何答案。任何从谷歌找到答案的人都可以告诉我你用什么关键词进行搜索?有时我发现很难确定要搜索的关键字。

ps2: I am too lazy, every I just open chrome and type something and search. If nothing found, I conclude nothing found and come here. Is there anyone will search on Google, then find nothing, then open bing.com and search? And find nothing and go to yahoo and search and search?.....

ps2:我太懒了,每次我都打开chrome并键入内容并搜索。如果一无所获,我得出的结论是什么,来到这里。有没有人会在Google上搜索,然后什么也找不到,然后打开bing.com并搜索?什么都没找到,去雅虎搜索和搜索?.....

5 个解决方案

#1


22  

It was always a pet peeve of mine to have to write out the RowDefinitions and ColumnDefinitions, so one day I got tired of it and wrote some attached properties that can be used for this kind of thing.

我不得不写出RowDefinitions和ColumnDefinitions,这总是令人讨厌,所以有一天我厌倦了它并编写了一些可用于此类事情的附加属性。

Now instead of writing my Grid definition like this:

现在不是像这样写我的Grid定义:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
</Grid>

I can use

我可以用

<Grid local:GridHelpers.RowCount="6"
      local:GridHelpers.StarRows="5"
      local:GridHelpers.ColumnCount="4"
      local:GridHelpers.StarColumns="1,3">

</Grid>

It only allows for Auto and * sizes, but most of the time that's all I'm using.

它只允许Auto和*尺寸,但大部分时间都是我正在使用的。

It also supports bindings for dynamically sized Grids

它还支持动态大小的网格的绑定

<Grid local:GridHelpers.RowCount="{Binding RowCount}"
      local:GridHelpers.ColumnCount="{Binding ColumnCount}" />

Here's a copy of the code in case that site ever goes down :

这是代码的副本,以防网站出现故障:

public class GridHelpers
{
    #region RowCount Property

    /// <summary>
    /// Adds the specified number of Rows to RowDefinitions. 
    /// Default Height is Auto
    /// </summary>
    public static readonly DependencyProperty RowCountProperty =
        DependencyProperty.RegisterAttached(
            "RowCount", typeof(int), typeof(GridHelpers),
            new PropertyMetadata(-1, RowCountChanged));

    // Get
    public static int GetRowCount(DependencyObject obj)
    {
        return (int)obj.GetValue(RowCountProperty);
    }

    // Set
    public static void SetRowCount(DependencyObject obj, int value)
    {
        obj.SetValue(RowCountProperty, value);
    }

    // Change Event - Adds the Rows
    public static void RowCountChanged(
        DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        if (!(obj is Grid) || (int)e.NewValue < 0)
            return;

        Grid grid = (Grid)obj;
        grid.RowDefinitions.Clear();

        for (int i = 0; i < (int)e.NewValue; i++)
            grid.RowDefinitions.Add(
                new RowDefinition() { Height = GridLength.Auto });

        SetStarRows(grid);
    }

    #endregion

    #region ColumnCount Property

    /// <summary>
    /// Adds the specified number of Columns to ColumnDefinitions. 
    /// Default Width is Auto
    /// </summary>
    public static readonly DependencyProperty ColumnCountProperty =
        DependencyProperty.RegisterAttached(
            "ColumnCount", typeof(int), typeof(GridHelpers),
            new PropertyMetadata(-1, ColumnCountChanged));

    // Get
    public static int GetColumnCount(DependencyObject obj)
    {
        return (int)obj.GetValue(ColumnCountProperty);
    }

    // Set
    public static void SetColumnCount(DependencyObject obj, int value)
    {
        obj.SetValue(ColumnCountProperty, value);
    }

    // Change Event - Add the Columns
    public static void ColumnCountChanged(
        DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        if (!(obj is Grid) || (int)e.NewValue < 0)
            return;

        Grid grid = (Grid)obj;
        grid.ColumnDefinitions.Clear();

        for (int i = 0; i < (int)e.NewValue; i++)
            grid.ColumnDefinitions.Add(
                new ColumnDefinition() { Width = GridLength.Auto });

        SetStarColumns(grid);
    }

    #endregion

    #region StarRows Property

    /// <summary>
    /// Makes the specified Row's Height equal to Star. 
    /// Can set on multiple Rows
    /// </summary>
    public static readonly DependencyProperty StarRowsProperty =
        DependencyProperty.RegisterAttached(
            "StarRows", typeof(string), typeof(GridHelpers),
            new PropertyMetadata(string.Empty, StarRowsChanged));

    // Get
    public static string GetStarRows(DependencyObject obj)
    {
        return (string)obj.GetValue(StarRowsProperty);
    }

    // Set
    public static void SetStarRows(DependencyObject obj, string value)
    {
        obj.SetValue(StarRowsProperty, value);
    }

    // Change Event - Makes specified Row's Height equal to Star
    public static void StarRowsChanged(
        DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        if (!(obj is Grid) || string.IsNullOrEmpty(e.NewValue.ToString()))
            return;

        SetStarRows((Grid)obj);
    }

    #endregion

    #region StarColumns Property

    /// <summary>
    /// Makes the specified Column's Width equal to Star. 
    /// Can set on multiple Columns
    /// </summary>
    public static readonly DependencyProperty StarColumnsProperty =
        DependencyProperty.RegisterAttached(
            "StarColumns", typeof(string), typeof(GridHelpers),
            new PropertyMetadata(string.Empty, StarColumnsChanged));

    // Get
    public static string GetStarColumns(DependencyObject obj)
    {
        return (string)obj.GetValue(StarColumnsProperty);
    }

    // Set
    public static void SetStarColumns(DependencyObject obj, string value)
    {
        obj.SetValue(StarColumnsProperty, value);
    }

    // Change Event - Makes specified Column's Width equal to Star
    public static void StarColumnsChanged(
        DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        if (!(obj is Grid) || string.IsNullOrEmpty(e.NewValue.ToString()))
            return;

        SetStarColumns((Grid)obj);
    }

    #endregion

    private static void SetStarColumns(Grid grid)
    {
        string[] starColumns = 
            GetStarColumns(grid).Split(',');

        for (int i = 0; i < grid.ColumnDefinitions.Count; i++)
        {
            if (starColumns.Contains(i.ToString()))
                grid.ColumnDefinitions[i].Width = 
                    new GridLength(1, GridUnitType.Star);
        }
    }

    private static void SetStarRows(Grid grid)
    {
        string[] starRows = 
            GetStarRows(grid).Split(',');

        for (int i = 0; i < grid.RowDefinitions.Count; i++)
        {
            if (starRows.Contains(i.ToString()))
                grid.RowDefinitions[i].Height = 
                    new GridLength(1, GridUnitType.Star);
        }
    }
}

#2


7  

Create attached dependency property with change callback to synchronize collection elements:

使用更改回调创建附加的依赖项属性以同步集合元素:

<Grid>
  <Grid.Style>
    <Style TargetType="Grid">
      <Setter Property="my:GridUtils.ColumnDefinitions">
        <Setter.Value>
          <my:ColumnDefinitionCollection>
            <ColumnDefinition Width="1*" />
            <ColumnDefinition Width="1*" />
          </my:ColumnDefinitionCollection>
        </Setter.Value>
      </Setter>
    </Style>
  </Grid.Style>

  <Button Content="Button" />
  <Button Content="Button" Grid.Column="1" />
</Grid>

Implementation (RowDefinition support omitted as it's basically identical):

实现(RowDefinition支持省略,因为它基本相同):

public class GridUtils
{
    public static readonly DependencyProperty ColumnDefinitionsProperty =
        DependencyProperty.RegisterAttached("ColumnDefinitions", typeof (ColumnDefinitionCollection),
                                            typeof (GridUtils),
                                            new PropertyMetadata(default(ColumnDefinitionCollection),
                                                                    OnColumnDefinitionsChanged));

    private static void OnColumnDefinitionsChanged(DependencyObject d, DependencyPropertyChangedEventArgs ev)
    {
        var grid = (Grid) d;
        var oldValue = (ColumnDefinitionCollection) ev.OldValue;
        var newValue = (ColumnDefinitionCollection) ev.NewValue;
        grid.ColumnDefinitions.Clear();
        if (newValue != null)
            foreach (var cd in newValue)
                grid.ColumnDefinitions.Add(cd);
    }

    public static void SetColumnDefinitions(Grid element, ColumnDefinitionCollection value)
    {
        element.SetValue(ColumnDefinitionsProperty, value);
    }

    public static ColumnDefinitionCollection GetColumnDefinitions(Grid element)
    {
        return (ColumnDefinitionCollection) element.GetValue(ColumnDefinitionsProperty);
    }
}

public class ColumnDefinitionCollection : List<ColumnDefinition> {}

#3


6  

I know this is an old question, but I would like to contribute with a solution which doesn't require any helper class.

我知道这是一个老问题,但我想提供一个不需要任何帮助类的解决方案。

It's possible to set ColumnDefinitions by using an ItemsControl with a Grid as its ItemsPanelTemplate. This is shown in the example below.

可以使用ItemsControl并将Grid作为ItemsPanelTemplate来设置ColumnDefinitions。这在下面的示例中显示。

<ItemsControl>
    <ItemsControl.Resources>
        <Style TargetType="ItemsControl">
            <Setter Property="ItemsPanel">
                <Setter.Value>
                    <ItemsPanelTemplate>
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition />
                                <ColumnDefinition Width="40" />
                            </Grid.ColumnDefinitions>
                        </Grid>
                    </ItemsPanelTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ItemsControl.Resources>
    <TextBox Text="First column" />
    <TextBox Text="second column" Grid.Column="1" />
</ItemsControl>

#4


1  

I believe it's not possible because you can't set a style that affects all ColumnDefinition(s).

我相信这是不可能的,因为你不能设置一个影响所有ColumnDefinition的样式。

Grid does not support ControlTemplate, so you can't do it with composition.

Grid不支持ControlTemplate,因此您无法使用合成。

The only hack I can think of would be to create a user control with those 2 columns and extend the grid. But that's nasty.

我能想到的唯一黑客就是用这两列创建一个用户控件并扩展网格。但那太讨厌了。

#5


0  

Here is a way:

这是一种方式:

1) Create a collection with an attached property like this:

1)创建一个带有附加属性的集合,如下所示:

public class ColumnDefinitions : Collection<ColumnDefinition>
{
    public static readonly DependencyProperty SourceProperty = DependencyProperty.RegisterAttached(
        "Source",
        typeof(ColumnDefinitions),
        typeof(ColumnDefinitions),
        new PropertyMetadata(
            default(ColumnDefinitions), 
            OnColumnDefinitionsChanged));

    public static void SetSource(Grid element, ColumnDefinitions value)
    {
        element.SetValue(SourceProperty, value);
    }

    [AttachedPropertyBrowsableForChildren(IncludeDescendants = false)]
    [AttachedPropertyBrowsableForType(typeof(Grid))]
    public static ColumnDefinitions GetSource(Grid element)
    {
        return (ColumnDefinitions)element.GetValue(SourceProperty);
    }

    private static void OnColumnDefinitionsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var grid = (Grid)d;
        grid.ColumnDefinitions.Clear();
        var columnDefinitions = (ColumnDefinitions)e.NewValue;
        if (columnDefinitions == null)
        {
            return;
        }

        foreach (var columnDefinition in columnDefinitions)
        {
            grid.ColumnDefinitions.Add(columnDefinition);
        }
    }
}

2) Then you can use it as a resource and in a style for grid like this:

2)然后你可以使用它作为资源和网格样式,如下所示:

Note that x:Shared="False" must be used. If not the same definition will be added to many grids causing WPF to throw.

请注意,必须使用x:Shared =“False”。如果没有相同的定义将添加到导致WPF抛出的许多网格中。

<UserControl.Resources>
    <demo:ColumnDefinitions x:Key="SomeColumnDefinitions" x:Shared="False">
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
    </demo:ColumnDefinitions>

    <Style x:Key="SomeGridStyle" TargetType="{x:Type Grid}">
        <Setter Property="demo:ColumnDefinitions.Source" Value="{StaticResource SomeColumnDefinitions}"></Setter>
    </Style>
</UserControl.Resources>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition  Height="5"/>
        <RowDefinition />
    </Grid.RowDefinitions>
    <Grid Style="{StaticResource SomeGridStyle}">
        <Rectangle Grid.Row="0"
                   Grid.Column="0"
                   Width="120"
                   Fill="Blue" />
        <Rectangle Grid.Row="0"
                   Grid.Column="1"
                   Fill="Yellow" />
    </Grid>

    <Grid Grid.Row="2" Style="{StaticResource SomeGridStyle}">
        <Rectangle Grid.Row="0"
                   Grid.Column="0"
                   Width="120"
                   Fill="Blue" />
        <Rectangle Grid.Row="0"
                   Grid.Column="1"
                   Fill="Yellow" />
    </Grid>
</Grid>

#1


22  

It was always a pet peeve of mine to have to write out the RowDefinitions and ColumnDefinitions, so one day I got tired of it and wrote some attached properties that can be used for this kind of thing.

我不得不写出RowDefinitions和ColumnDefinitions,这总是令人讨厌,所以有一天我厌倦了它并编写了一些可用于此类事情的附加属性。

Now instead of writing my Grid definition like this:

现在不是像这样写我的Grid定义:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
</Grid>

I can use

我可以用

<Grid local:GridHelpers.RowCount="6"
      local:GridHelpers.StarRows="5"
      local:GridHelpers.ColumnCount="4"
      local:GridHelpers.StarColumns="1,3">

</Grid>

It only allows for Auto and * sizes, but most of the time that's all I'm using.

它只允许Auto和*尺寸,但大部分时间都是我正在使用的。

It also supports bindings for dynamically sized Grids

它还支持动态大小的网格的绑定

<Grid local:GridHelpers.RowCount="{Binding RowCount}"
      local:GridHelpers.ColumnCount="{Binding ColumnCount}" />

Here's a copy of the code in case that site ever goes down :

这是代码的副本,以防网站出现故障:

public class GridHelpers
{
    #region RowCount Property

    /// <summary>
    /// Adds the specified number of Rows to RowDefinitions. 
    /// Default Height is Auto
    /// </summary>
    public static readonly DependencyProperty RowCountProperty =
        DependencyProperty.RegisterAttached(
            "RowCount", typeof(int), typeof(GridHelpers),
            new PropertyMetadata(-1, RowCountChanged));

    // Get
    public static int GetRowCount(DependencyObject obj)
    {
        return (int)obj.GetValue(RowCountProperty);
    }

    // Set
    public static void SetRowCount(DependencyObject obj, int value)
    {
        obj.SetValue(RowCountProperty, value);
    }

    // Change Event - Adds the Rows
    public static void RowCountChanged(
        DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        if (!(obj is Grid) || (int)e.NewValue < 0)
            return;

        Grid grid = (Grid)obj;
        grid.RowDefinitions.Clear();

        for (int i = 0; i < (int)e.NewValue; i++)
            grid.RowDefinitions.Add(
                new RowDefinition() { Height = GridLength.Auto });

        SetStarRows(grid);
    }

    #endregion

    #region ColumnCount Property

    /// <summary>
    /// Adds the specified number of Columns to ColumnDefinitions. 
    /// Default Width is Auto
    /// </summary>
    public static readonly DependencyProperty ColumnCountProperty =
        DependencyProperty.RegisterAttached(
            "ColumnCount", typeof(int), typeof(GridHelpers),
            new PropertyMetadata(-1, ColumnCountChanged));

    // Get
    public static int GetColumnCount(DependencyObject obj)
    {
        return (int)obj.GetValue(ColumnCountProperty);
    }

    // Set
    public static void SetColumnCount(DependencyObject obj, int value)
    {
        obj.SetValue(ColumnCountProperty, value);
    }

    // Change Event - Add the Columns
    public static void ColumnCountChanged(
        DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        if (!(obj is Grid) || (int)e.NewValue < 0)
            return;

        Grid grid = (Grid)obj;
        grid.ColumnDefinitions.Clear();

        for (int i = 0; i < (int)e.NewValue; i++)
            grid.ColumnDefinitions.Add(
                new ColumnDefinition() { Width = GridLength.Auto });

        SetStarColumns(grid);
    }

    #endregion

    #region StarRows Property

    /// <summary>
    /// Makes the specified Row's Height equal to Star. 
    /// Can set on multiple Rows
    /// </summary>
    public static readonly DependencyProperty StarRowsProperty =
        DependencyProperty.RegisterAttached(
            "StarRows", typeof(string), typeof(GridHelpers),
            new PropertyMetadata(string.Empty, StarRowsChanged));

    // Get
    public static string GetStarRows(DependencyObject obj)
    {
        return (string)obj.GetValue(StarRowsProperty);
    }

    // Set
    public static void SetStarRows(DependencyObject obj, string value)
    {
        obj.SetValue(StarRowsProperty, value);
    }

    // Change Event - Makes specified Row's Height equal to Star
    public static void StarRowsChanged(
        DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        if (!(obj is Grid) || string.IsNullOrEmpty(e.NewValue.ToString()))
            return;

        SetStarRows((Grid)obj);
    }

    #endregion

    #region StarColumns Property

    /// <summary>
    /// Makes the specified Column's Width equal to Star. 
    /// Can set on multiple Columns
    /// </summary>
    public static readonly DependencyProperty StarColumnsProperty =
        DependencyProperty.RegisterAttached(
            "StarColumns", typeof(string), typeof(GridHelpers),
            new PropertyMetadata(string.Empty, StarColumnsChanged));

    // Get
    public static string GetStarColumns(DependencyObject obj)
    {
        return (string)obj.GetValue(StarColumnsProperty);
    }

    // Set
    public static void SetStarColumns(DependencyObject obj, string value)
    {
        obj.SetValue(StarColumnsProperty, value);
    }

    // Change Event - Makes specified Column's Width equal to Star
    public static void StarColumnsChanged(
        DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        if (!(obj is Grid) || string.IsNullOrEmpty(e.NewValue.ToString()))
            return;

        SetStarColumns((Grid)obj);
    }

    #endregion

    private static void SetStarColumns(Grid grid)
    {
        string[] starColumns = 
            GetStarColumns(grid).Split(',');

        for (int i = 0; i < grid.ColumnDefinitions.Count; i++)
        {
            if (starColumns.Contains(i.ToString()))
                grid.ColumnDefinitions[i].Width = 
                    new GridLength(1, GridUnitType.Star);
        }
    }

    private static void SetStarRows(Grid grid)
    {
        string[] starRows = 
            GetStarRows(grid).Split(',');

        for (int i = 0; i < grid.RowDefinitions.Count; i++)
        {
            if (starRows.Contains(i.ToString()))
                grid.RowDefinitions[i].Height = 
                    new GridLength(1, GridUnitType.Star);
        }
    }
}

#2


7  

Create attached dependency property with change callback to synchronize collection elements:

使用更改回调创建附加的依赖项属性以同步集合元素:

<Grid>
  <Grid.Style>
    <Style TargetType="Grid">
      <Setter Property="my:GridUtils.ColumnDefinitions">
        <Setter.Value>
          <my:ColumnDefinitionCollection>
            <ColumnDefinition Width="1*" />
            <ColumnDefinition Width="1*" />
          </my:ColumnDefinitionCollection>
        </Setter.Value>
      </Setter>
    </Style>
  </Grid.Style>

  <Button Content="Button" />
  <Button Content="Button" Grid.Column="1" />
</Grid>

Implementation (RowDefinition support omitted as it's basically identical):

实现(RowDefinition支持省略,因为它基本相同):

public class GridUtils
{
    public static readonly DependencyProperty ColumnDefinitionsProperty =
        DependencyProperty.RegisterAttached("ColumnDefinitions", typeof (ColumnDefinitionCollection),
                                            typeof (GridUtils),
                                            new PropertyMetadata(default(ColumnDefinitionCollection),
                                                                    OnColumnDefinitionsChanged));

    private static void OnColumnDefinitionsChanged(DependencyObject d, DependencyPropertyChangedEventArgs ev)
    {
        var grid = (Grid) d;
        var oldValue = (ColumnDefinitionCollection) ev.OldValue;
        var newValue = (ColumnDefinitionCollection) ev.NewValue;
        grid.ColumnDefinitions.Clear();
        if (newValue != null)
            foreach (var cd in newValue)
                grid.ColumnDefinitions.Add(cd);
    }

    public static void SetColumnDefinitions(Grid element, ColumnDefinitionCollection value)
    {
        element.SetValue(ColumnDefinitionsProperty, value);
    }

    public static ColumnDefinitionCollection GetColumnDefinitions(Grid element)
    {
        return (ColumnDefinitionCollection) element.GetValue(ColumnDefinitionsProperty);
    }
}

public class ColumnDefinitionCollection : List<ColumnDefinition> {}

#3


6  

I know this is an old question, but I would like to contribute with a solution which doesn't require any helper class.

我知道这是一个老问题,但我想提供一个不需要任何帮助类的解决方案。

It's possible to set ColumnDefinitions by using an ItemsControl with a Grid as its ItemsPanelTemplate. This is shown in the example below.

可以使用ItemsControl并将Grid作为ItemsPanelTemplate来设置ColumnDefinitions。这在下面的示例中显示。

<ItemsControl>
    <ItemsControl.Resources>
        <Style TargetType="ItemsControl">
            <Setter Property="ItemsPanel">
                <Setter.Value>
                    <ItemsPanelTemplate>
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition />
                                <ColumnDefinition Width="40" />
                            </Grid.ColumnDefinitions>
                        </Grid>
                    </ItemsPanelTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ItemsControl.Resources>
    <TextBox Text="First column" />
    <TextBox Text="second column" Grid.Column="1" />
</ItemsControl>

#4


1  

I believe it's not possible because you can't set a style that affects all ColumnDefinition(s).

我相信这是不可能的,因为你不能设置一个影响所有ColumnDefinition的样式。

Grid does not support ControlTemplate, so you can't do it with composition.

Grid不支持ControlTemplate,因此您无法使用合成。

The only hack I can think of would be to create a user control with those 2 columns and extend the grid. But that's nasty.

我能想到的唯一黑客就是用这两列创建一个用户控件并扩展网格。但那太讨厌了。

#5


0  

Here is a way:

这是一种方式:

1) Create a collection with an attached property like this:

1)创建一个带有附加属性的集合,如下所示:

public class ColumnDefinitions : Collection<ColumnDefinition>
{
    public static readonly DependencyProperty SourceProperty = DependencyProperty.RegisterAttached(
        "Source",
        typeof(ColumnDefinitions),
        typeof(ColumnDefinitions),
        new PropertyMetadata(
            default(ColumnDefinitions), 
            OnColumnDefinitionsChanged));

    public static void SetSource(Grid element, ColumnDefinitions value)
    {
        element.SetValue(SourceProperty, value);
    }

    [AttachedPropertyBrowsableForChildren(IncludeDescendants = false)]
    [AttachedPropertyBrowsableForType(typeof(Grid))]
    public static ColumnDefinitions GetSource(Grid element)
    {
        return (ColumnDefinitions)element.GetValue(SourceProperty);
    }

    private static void OnColumnDefinitionsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var grid = (Grid)d;
        grid.ColumnDefinitions.Clear();
        var columnDefinitions = (ColumnDefinitions)e.NewValue;
        if (columnDefinitions == null)
        {
            return;
        }

        foreach (var columnDefinition in columnDefinitions)
        {
            grid.ColumnDefinitions.Add(columnDefinition);
        }
    }
}

2) Then you can use it as a resource and in a style for grid like this:

2)然后你可以使用它作为资源和网格样式,如下所示:

Note that x:Shared="False" must be used. If not the same definition will be added to many grids causing WPF to throw.

请注意,必须使用x:Shared =“False”。如果没有相同的定义将添加到导致WPF抛出的许多网格中。

<UserControl.Resources>
    <demo:ColumnDefinitions x:Key="SomeColumnDefinitions" x:Shared="False">
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
    </demo:ColumnDefinitions>

    <Style x:Key="SomeGridStyle" TargetType="{x:Type Grid}">
        <Setter Property="demo:ColumnDefinitions.Source" Value="{StaticResource SomeColumnDefinitions}"></Setter>
    </Style>
</UserControl.Resources>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition  Height="5"/>
        <RowDefinition />
    </Grid.RowDefinitions>
    <Grid Style="{StaticResource SomeGridStyle}">
        <Rectangle Grid.Row="0"
                   Grid.Column="0"
                   Width="120"
                   Fill="Blue" />
        <Rectangle Grid.Row="0"
                   Grid.Column="1"
                   Fill="Yellow" />
    </Grid>

    <Grid Grid.Row="2" Style="{StaticResource SomeGridStyle}">
        <Rectangle Grid.Row="0"
                   Grid.Column="0"
                   Width="120"
                   Fill="Blue" />
        <Rectangle Grid.Row="0"
                   Grid.Column="1"
                   Fill="Yellow" />
    </Grid>
</Grid>