Is it possible to configure a GridView to show pivoted data using static XAML if column info is unknown at design time?

China☆狼群 提交于 2019-12-24 01:56:20

问题


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


回答1:


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.



来源:https://stackoverflow.com/questions/1156336/is-it-possible-to-configure-a-gridview-to-show-pivoted-data-using-static-xaml-if

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!