如何在 Grid.Row/Grid.Column 中引用行/列定义? [英] How to reference a row/column definition in 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屋!