XAML:我可以按名称引用Grid行或列吗? [英] XAML: Can I refer to a Grid row or column by name?

查看:96
本文介绍了XAML:我可以按名称引用Grid行或列吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我为网格中的每一行和每一列命名,是否可以设置控件的grid.row = Row_Top?我已经定义了StaticResources来引用它,但是是否有转换器或其他方法可以在没有资源的情况下完成此任务?

If I name each row and column in a grid, can I set a control's grid.row="Row_Top"? I have defined StaticResources to refer to it but is there a converter or some other method to accomplish this without the resource?

推荐答案

As据我所知,没有内置方法可以执行此操作...但是,您可以使用标记扩展名来按名称检索行或列:

As far as I know there's no built-in way to do it... however, you could use markup extensions to retrieve a row or column by its name :

[MarkupExtensionReturnType(typeof(int))]
public abstract class GridBandExtensionBase : MarkupExtension
{
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        if (serviceProvider != null)
        {
            var target = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
            if (target != null)
            {
                var obj = target.TargetObject as DependencyObject;
                if (obj != null)
                {
                    var grid = VisualTreeHelper.GetParent(obj) as Grid;
                    if (grid != null)
                    {
                        return GetBandIndex(grid);
                    }
                }
            }
        }
        return 0;
    }

    protected abstract int GetBandIndex(Grid grid);
}

public class GridRowExtension : GridBandExtensionBase
{
    public GridRowExtension() {}

    public GridRowExtension(string rowName)
    {
        this.RowName = rowName;
    }

    [ConstructorArgument("rowName")]
    public string RowName { get; set; }

    protected override int GetBandIndex(System.Windows.Controls.Grid grid)
    {
        for (int i = 0; i < grid.RowDefinitions.Count; i++)
        {
            if (grid.RowDefinitions[i].Name == RowName)
            {
                return i;
            }
        }
        return 0;
    }
}

public class GridColumnExtension : GridBandExtensionBase
{
    public GridColumnExtension() {}

    public GridColumnExtension(string columnName)
    {
        this.ColumnName = columnName;
    }

    [ConstructorArgument("columnName")]
    public string ColumnName { get; set; }

    protected override int GetBandIndex(System.Windows.Controls.Grid grid)
    {
        for (int i = 0; i < grid.ColumnDefinitions.Count; i++)
        {
            if (grid.ColumnDefinitions[i].Name == ColumnName)
            {
                return i;
            }
        }
        return 0;
    }
}

您可以按以下方式使用这些扩展名:

You could then use these extensions as follows :

<Button Grid.Row="{my:GridRow Row_Top}"
        Grid.Column="{my:GridColumn Column_Right}"
        Content="Hello world" />

注意:,如果您在与您相同的程序集中编译这些标记扩展名应用程序,设计人员将无法使用参数调用构造函数(但在运行时可以正常工作)。这是已知错误。如果希望它在设计时起作用,请将标记扩展名放在单独的程序集中,或显式指定RowName / ColumnName属性,如下所示:

NOTE: if you compile these markup extensions in the same assembly as your application, the designer won't be able to call the constructor with a parameter (but it will work fine at runtime). This is a known bug that Microsoft doesn't intend to fix. If you want it to work at design time, put the markup extension in a separate assembly, or specify the RowName/ColumnName properties explicitly, as follows :

<Button Grid.Row="{my:GridRow RowName=Row_Top}"
        Grid.Column="{my:GridColumn ColumnName=Column_Right}"
        Content="Hello world" />

这篇关于XAML:我可以按名称引用Grid行或列吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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