如果列信息在设计时未知,可以使用静态XAML来配置GridView来显示枢轴数据吗? [英] Is it possible to configure a GridView to show pivoted data using static XAML if column info is unknown at design time?

查看:127
本文介绍了如果列信息在设计时未知,可以使用静态XAML来配置GridView来显示枢轴数据吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近我最近在运行时使用XamlReader.Parse()来生成和加载XAML标记。我被告知,没有理由使用XamlReader - 它可以随时使用静态XAML,在设计时预先确定。



我试图问这个人我可以构造一个GridView来显示枢轴数据,其中每列的列数和绑定路径在设计时是未知的。我还没有回覆,但即使我这样做,我认为这将是一个有趣的问题,因为它可能会打开我的眼睛(和其他人)更好的做事情。



我的具体情况:每个参与者预计会执行一定数量的块,但是我不知道有多少块,直到我从数据库中获取数据。考虑到这个背景,我的目标是显示一个具有以下列的GridView:

 参与者|块1 |块2 | ... |块N | 
(其中N是块的总数)

我目前的策略是动态循环通过街区。对于每个块,我实例化一个新的GridViewColumn,生成自定义XAML以形成基于BlockIndex的DataTemplate,并使用XamlReader.Parse()设置列的CellTemplate。



这是代码,只是为了确保我清楚:

  public void AddParticipantGridViewColumns()
{
GridView view =(GridView)_participantListView.View;
GridViewColumn列;
SetupViewModel setupViewModel =(SetupViewModel)DataContext;
foreach(int blockIndex in setupViewModel.BlockIndices)
{
column = BuildParticipantGridViewColumn(blockIndex);
view.Columns.Add(column);
}
}

public virtual GridViewColumn BuildParticipantGridViewColumn(int blockIndex)
{
string templateXaml = string.Format(@
< DataTemplate
xmlns =http://schemas.microsoft.com/winfx/2006/xaml/presentation
xmlns:x =http://schemas.microsoft.com/winfx/ 2006 / xaml
xmlns:local =clr-namespace:Pse.ExperimentBase; assembly = ExperimentBase>
< DataTemplate.Resources>
< local:BlockToBrushConverter
x:Key =_ blockToBrushConverter/>
< /DataTemplate.Resources>
< TextBlock
Style ={{StaticResource _gridViewCenterItemStyle}}
Text ={{Binding Path = Block {0} .ConditionLabel}}
Foreground ={{Binding Path = Block {0},Converter = {{StaticResource _blockToBrushConverter}}}} />
< / DataTemplate>,
blockIndex);
GridViewColumn column = new GridViewColumn();
column.Header = string.Format(Block {0},blockIndex);
column.CellTemplate =(DataTemplate)XamlReader.Parse(templateXaml);
返回列;
}

有没有一些聪明的方式,我可以单独使用静态XAML来做到这一点,或者是动态的解决方案,就像我在这里介绍的那样,唯一实际的做法呢?另外,如果有一个静态解决方案,你会不会喜欢动态的?



谢谢,



-Dan

解决方案

我不认为有一个直截了当的方式来完成 XAML,但是绝对存在比你更为静态的解决方案。主要的问题不在于您正在尝试在代码隐藏中动态设置GridView(这是预期会出现这样的问题),而是您正在解析相同的XAML标记 N 次代码隐藏。这样的DataTemplate应该始终在标记文件中找到,而不是方法中的字符串。在您的示例中,您应该在定义_participantListView的XAML文件中定义数据模板。


I was recently, um, chastised for generating and loading XAML markup at runtime using XamlReader.Parse(). I was told that there's no reason to use XamlReader--it can always be done with static XAML, predetermined at design time.

I attempted to ask this person how I could construct a GridView to show pivoted data, where the number of columns and the binding path for each column is unknown at design time. I have yet to hear back, but even if I did, I figured this would be an interesting question to ask, because it might open my eyes (and others') to a better way of doing things.

My specific situation: Each "participant" is expected to perform a certain number of "blocks", but I don't know how many blocks there will be until I grab that data from the database. With that background in mind, my goal is to show a GridView that has the following columns:

Participant | Block 1 | Block 2 | ... | Block N |
(where N is the total number of blocks)

My current strategy is to dynamically loop through the blocks. For each block, I instantiate a new GridViewColumn, generate custom XAML to form a DataTemplate based on the BlockIndex, and use XamlReader.Parse() to set the column's CellTemplate.

Here is the code, just to make sure I'm being clear:

public void AddParticipantGridViewColumns()
{
    GridView view = (GridView)_participantListView.View;
    GridViewColumn column;
    SetupViewModel setupViewModel = (SetupViewModel)DataContext;
    foreach (int blockIndex in setupViewModel.BlockIndices)
    {
        column = BuildParticipantGridViewColumn(blockIndex);
        view.Columns.Add(column);
    }
}

public virtual GridViewColumn BuildParticipantGridViewColumn(int blockIndex)
{
    string templateXaml = string.Format(@"
        <DataTemplate
            xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
            xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""
            xmlns:local=""clr-namespace:Pse.ExperimentBase;assembly=ExperimentBase"">        
            <DataTemplate.Resources>
                <local:BlockToBrushConverter
                    x:Key=""_blockToBrushConverter"" />
            </DataTemplate.Resources>
            <TextBlock
                Style=""{{StaticResource _gridViewCenterItemStyle}}""
                Text=""{{Binding Path=Block{0}.ConditionLabel}}""
                Foreground=""{{Binding Path=Block{0}, Converter={{StaticResource _blockToBrushConverter}}}}"" />
        </DataTemplate>",
        blockIndex);
    GridViewColumn column = new GridViewColumn();
    column.Header = string.Format("Block {0}", blockIndex);
    column.CellTemplate = (DataTemplate)XamlReader.Parse(templateXaml);
    return column;
}

Is there some clever way I could do this with static XAML alone or is a dynamic solution, like the one I presented here, the only practical way to do it? Also, if there is a static solution, would you actually prefer it to the dynamic one?

Thanks,

-Dan

解决方案

I don't think there is a straightforward way to do it entirely in XAML, but there definitely exists a more static solution than yours. The main problem is not that you are trying to dynamically set up your GridView in the code-behind (that's to be expected with a problem like this), but that you are parsing the same XAML mark-up N times in the code-behind. A DataTemplate such as this should always be found in a mark-up file, not as a string inside a method. In your example, it appears you should define the data-template in the XAML file where your _participantListView is defined.

这篇关于如果列信息在设计时未知,可以使用静态XAML来配置GridView来显示枢轴数据吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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