基于WinRT中的单独ViewModel属性更改GridView项DataTemplate

时间:2013-12-17 20:50:29

标签: c# gridview windows-runtime winrt-xaml datatemplate

我尝试做的是在GridView控件中显示一组项目,并根据单独按钮执行的命令更改这些项目的大小。

例如,在顶部读取“Small”,“Medium”和“Large”的一行按钮,并使GridView中的项目通过在相关状态下显示其项目来响应相关命令。

我将gridview声明为

<GridView ItemsSource="{Binding Squares}"

Squares是一个可观察的Square对象集合,具有Title和Fill属性。

首先,我通过在页面的参考资料部分声明以下数据模板来关闭DataTemplateSelector路径。

<DataTemplate x:Key="SquareSmallTemplate">
        <Grid Height="100" Width="100">
            <Rectangle Fill="{Binding Fill}"/>
            <TextBlock Text="{Binding Title}"/>
        </Grid>
    </DataTemplate>

    <DataTemplate x:Key="SquareMediumTemplate">
        <Grid Height="150" Width="150">
            <Rectangle Fill="{Binding Fill}"/>
            <TextBlock Text="{Binding Title}"/>
        </Grid>
    </DataTemplate>

    <DataTemplate x:Key="SquareLargeTemplate">
        <Grid Height="200" Width="200">
            <Rectangle Fill="{Binding Fill}"/>
            <TextBlock Text="{Binding Title}"/>
        </Grid>
    </DataTemplate>

这个想法是网格的高度和宽度属性对于相关模板是不同的。我在选择器

中声明了以下数据模板
public DataTemplate SmallTemplate { get; set; }
public DataTemplate MediumTemplate { get; set; }
public DataTemplate LargeTemplate { get; set; }

在SelecteTemplateCore方法中,我刚刚返回了相关的模板

protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
    {
        string value = item as string;

        if (value != null)
        {
            if (value == "Small")
                return SmallTemplate;
            else if (value == "Medium")
                return MediumTemplate;
            else if (value == "Large")
                return LargeTemplate;
            return base.SelectTemplate(item, container);
        }
        else
        {
            return base.SelectTemplateCore(item, container);
        }            
    }

但是,使用此方法(并且,通过设计DataTemplateSelector),传入的对象是集合中的项目(Square)。

如果我希望每个项目具有不同的外观或其他东西,这很好,但我需要的是根据视图模型上的另一个属性进行更改的模板。

为此,我有以下

public string State {get; set;}

,根据执行将此属性设置为相关值的命令的三个按钮的单独行,将其设置为“Small”,“Medium”或“Large”。

如何将State属性与更改为相关的DataTemplate相关联?

我尝试的另一条路线是使用单个数据模板,该模板使用VSM为相关状态中的高度/宽度属性设置动画。但是当状态改变时,我无法获得相关的动画。

任何帮助都会很棒,谢谢

1 个答案:

答案 0 :(得分:0)

有几种方法可以做到这一点,我不确定哪种方法最好。在任何情况下,您都需要1)触发器,以及2)更新模板的操作。我倾向于使用PropertyChangedTriggerInvokeCommandAction

<GridView x:Name="grid">
    <i:Interaction.Triggers>
        <ei:PropertyChangedTrigger Binding="{Binding State}">
            <i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=UpdateTemplateCommand}" CommandParameter="{Binding State}" />
        </ei:PropertyChangedTrigger>
    </i:Interaction.Triggers>
<GridView>

(这里“AncestorType”只是视图的根,所以请根据需要更改“UserControl”。)

然后在视图中,您将拥有一个更新模板的ICommand

 UpdateTemplateCommand = new DelegateCommand(state => {
     switch ((string)state)
     {
         default:
         case "Small" : grid.ItemTemplate = "SquareSmallTemplate"; break;
         case "Medium" : grid.ItemTemplate = "SquareMediumTemplate"; break;
         case "Large" : grid.ItemTemplate = "SquareLargeTemplate"; break;
     }
 });
IDK ......写完之后似乎有点费解。也许您会发现最好向视图模型添加CurrentDataTemplate属性,并使用DataTemplate通过字符串创建XamlReader来分配它。