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

Gar*_*ryX 16 wpf grid

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

<Grid.ColumnDefinitions>
   <ColumnDefinition Width="auto" SharedSizeGroup="SG1"/>
   <ColumnDefinition Width="auto" SharedSizeGroup="SG2"/>
</Grid.ColumnDefinitions>
Run Code Online (Sandbox Code Playgroud)

每次?

非常感谢你!

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

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

Rac*_*hel 23

这一直是我的一个忌讳有写出来的RowDefinitionsColumnDefinitions,所以有一天我厌倦了,并写了一些附加属性,可以用于这种东西.

现在不是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>
Run Code Online (Sandbox Code Playgroud)

我可以用

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

</Grid>
Run Code Online (Sandbox Code Playgroud)

它只允许Auto*大小,但大部分时间都是我正在使用的.

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

<Grid local:GridHelpers.RowCount="{Binding RowCount}"
      local:GridHelpers.ColumnCount="{Binding ColumnCount}" />
Run Code Online (Sandbox Code Playgroud)

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

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 12

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

可以使用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>
Run Code Online (Sandbox Code Playgroud)


Mar*_*cki 7

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

<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>
Run Code Online (Sandbox Code Playgroud)

实现(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> {}
Run Code Online (Sandbox Code Playgroud)


key*_*yle 1

我相信这是不可能的,因为您无法设置影响所有 ColumnDefinition 的样式。

Grid 不支持 ControlTemplate,因此无法通过组合来实现。

我能想到的唯一黑客是使用这两列创建一个用户控件并扩展网格。但这很糟糕。