如何在 Grid.Row/Grid.Column 中引用行/列定义? [英] How to reference a row/column definition in Grid.Row/Grid.Column?

查看:63
本文介绍了如何在 Grid.Row/Grid.Column 中引用行/列定义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这可能很明显...我稍后如何在同一个 XAML 文件中引用 XAML 元素?

This may be obvious... How do I reference XAML elements later in that same XAML file?

示例:

<Grid.RowDefinitions>
    <RowDefinition Height="661*" Name="someGridRow" />
    <RowDefinition Height="230*" Name="someOtherGridRow"/>
</Grid.RowDefinitions>

然后我在网格内定义了各种控件,我想通过名称而不是数字来引用这些行:

Then I define various controls inside the grid and I'd like to reference these rows by name, not by number:

<RichTextBox Grid.Row="someGridRow" ... />

因为如果我在很多控件上使用 Grid.Row="0" ,那么当我在第一行之前添加一行时,我必须更改对 Grid.Row 的所有引用="1" 手动.

Because if I use Grid.Row="0" on many controls, then when I add a row before the first row, I have to change all the references to Grid.Row="1" by hand.

编辑:

感谢答案,我一直在阅读有关 XAML 的一些内容.

Thanks to the answers I have been reading a bit on XAML.

毕竟,显然可以通过名称引用前一个元素:

After all, it IS possible to reference a previous element by name apparently:

Grid.Row="{Binding ElementName=someGridRow}"

Grid.Row="{x:Reference someGridRow}"

但这并不能完全解决问题,因为 Grid.Row 需要一个 int,而 someGridRow 不是一个 int,它是一个 System.Windows.Controls.RowDefinition.

but this doesn't solve the problem entirely because Grid.Row requires an int, whereas someGridRow is not an int, it's a System.Windows.Controls.RowDefinition.

所以需要的是

Grid.Row = grid.RowDefinitions.IndexOf(someGridRow)

在后面的代码中会被写成

which in code behind would be written

Grid.SetRow(richTextBox, grid.RowDefinitions.IndexOf(someGridRow))

或将 Grid.Row 绑定到对象 grid 上的属性,该对象的路径为 "RowDefinitions.IndexOf"使用参数 someGridRow:

or do a binding of Grid.Row to the property, on the object grid, which has the path "RowDefinitions.IndexOf" with the parameter someGridRow:

PropertyPath path = new PropertyPath("RowDefinitions.IndexOf", someGridRow);
Binding binding = new Binding() { ElementName = "grid", Path = path };
richTextBox.SetBinding(Grid.RowProperty, binding);

(这实际上在 C# 中不起作用,所以我一定是做错了什么,尽管上面的 Grid.SetRow 确实有效)

(this actually doesn't work in C#, so I must be doing something wrong, although Grid.SetRow above does work)

XAML 2009 定义了 来调用具有参数的构造函数.如果这在 WPF XAML 中有效,那么我想这样的事情会起作用吗?

XAML 2009 defines <x:Arguments> to invoke constructors which have parameters. If that worked in WPF XAML, then something like that would work I suppose?

<Grid.Row>
  <Binding ElementName="grid">
    <Binding.Path>
      <PropertyPath>
        <x:Arguments>
          RowDefinitions.IndexOf
          <Binding ElementName="someGridRow"/>
        </x:Arguments>
      </PropertyPath>
    </Binding.Path>
  </Binding>
</Grid.Row>

where <Binding ElementName="someGridRow"/> 在 XAML 2009 中也可以替换为 <x:Reference Name="someGridRow"/>.

where <Binding ElementName="someGridRow"/> can also be replaced by <x:Reference Name="someGridRow"/> in XAML 2009.

推荐答案

对于 lulz:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Markup;
using System.Windows.Controls;
using System.Windows;

namespace Test.MarkupExtensions
{
    class GridDefinitionExtension : MarkupExtension
    {
        public string Name { get; set; }

        public GridDefinitionExtension(string name)
        {
            Name = name;
        }

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            var refExt = new Reference(Name);
            var definition = refExt.ProvideValue(serviceProvider);
            if (definition is DefinitionBase)
            {
                var grid = (definition as FrameworkContentElement).Parent as Grid;
                if (definition is RowDefinition)
                {
                    return grid.RowDefinitions.IndexOf(definition as RowDefinition);
                }
                else
                {
                    return grid.ColumnDefinitions.IndexOf(definition as ColumnDefinition);
                }
            }
            else
            {
                throw new Exception("Found object is neither a RowDefinition nor a ColumnDefinition");
            }
        }
    }
}

<Grid Width="200" Height="200"
      xmlns:me="clr-namespace:Test.MarkupExtensions">
    <Grid.RowDefinitions>
        <RowDefinition Name="row1" />
        <RowDefinition Name="row2" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Name="col1" />
        <ColumnDefinition Name="col2" />
    </Grid.ColumnDefinitions>
    <Border Background="Lime" Grid.Row="{me:GridDefinition row1}" Grid.Column="{me:GridDefinition col1}" />
    <Border Background="Red" Grid.Row="{me:GridDefinition row2}" Grid.Column="{me:GridDefinition col1}" />
    <Border Background="Yellow" Grid.Row="{me:GridDefinition row1}" Grid.Column="{me:GridDefinition col2}" />
    <Border Background="Blue" Grid.Row="{me:GridDefinition row2}" Grid.Column="{me:GridDefinition col2}" />
</Grid>

这篇关于如何在 Grid.Row/Grid.Column 中引用行/列定义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆