Vista的风格的ListView(GridViewRow presenter) [英] Vista style ListView (GridViewRowPresenter)

查看:249
本文介绍了Vista的风格的ListView(GridViewRow presenter)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想显示的ListView 不同行(不同的风格和不同的内容)的数据。但只要我尝试应用样式(其中假设改变什么)选择停止工作,它不再 Vista的风格

我是什么做错了吗?也许是错误的做法?

 < ListView控件的ItemsSource ={结合A}>
    < ListView.View>
        <&GridView的GT;
            < GridViewColumn标题=BDisplayMemberBinding ={结合B}/>
            ...
        < / GridView的>
    < /ListView.View>    <! - 在下面评论块将返回Vista的风格回归 - >
    < ListView.ItemContainerStyle>
        <风格的TargetType =ListViewItem的>
            < setter属性=模板>
                < Setter.Value>
                    <的ControlTemplate的TargetType =ListViewItem的>
                        < GridViewRow presenter CONTENT ={TemplateBinding内容}/>
                    < /控件模板>
                < /Setter.Value>
            < /二传手>
        < /样式和GT;
    < /ListView.ItemContainerStyle>
< /&的ListView GT;


解决方案

我尽量保持尽可能通用,所以我定义为不同类型的简单枚举每一行可以采取:

 公共枚举ROWTYPE {BOOL,的Int32}

现在我用它为行视图模型:

 公共类行:DependencyObject的
{
    //创建一个新的行与给定值
    //基础上,参数自动设定值时,信息和ROWTYPE
    公共行(对象VAL)
    {
        值= VAL;
        如果(val.GetType()== typeof运算(布尔))ROWTYPE = WpfApplication3.RowType.Bool;
        否则ROWTYPE = WpfApplication3.RowType.Int32;
        信息= val.ToString()+型的+ val.GetType()的ToString();
    }    公共ROWTYPE ROWTYPE {搞定;组; }    ///<总结>
    ///获取或设置一个可绑定值,指示值
    ///< /总结>
    公共对象值
    {
        {返回(对象)的GetValue(ValueProperty); }
        集合{的SetValue(ValueProperty,值); }
    }
    公共静态只读的DependencyProperty ValueProperty =
        DependencyProperty.Register(值的typeof(对象)的typeof(行​​),新PropertyMetadata(0));    ///<总结>
    ///获取或设置一个可绑定值,指示信息
    ///< /总结>
    公共字符串信息
    {
        {返回(串)的GetValue(InfoProperty); }
        集合{的SetValue(InfoProperty,值); }
    }
    公共静态只读的DependencyProperty InfoProperty =
        DependencyProperty.Register(信息的typeof(串)的typeof(行​​),新PropertyMetadata());
}

现在,该视图模型已经准备好,我创建了一个简单TemplateSelector这是为了响应给定行的行类型:

 公共类选择:DataTemplateSelector
{
    //模板行类型==布尔
    公众的DataTemplate模板1 {搞定;组; }
    //模板行类型==的Int32
    公众的DataTemplate则Template2 {搞定;组; }    公众覆盖的DataTemplate SelectTemplate(对象项目,DependencyObject的容器)
    {
        VAR行=项目作为行;
        如果(行== NULL)返回NULL;        开关(row.RowType)
        {
            案例RowType.Bool:
                返回模板1;
            案例RowType.Int32:
                返回则Template2;
            默认:
                返回null;
        }
    }
}

和我用它在XAML是这样的:

 < Window.Resources>    <! - 为COLUMN1选择CellTemplate基于ROWTYPE(价值) -  GT;
    <局部:选择X:键=valueSelector>
        <局部:Selector.Template1>
            <&DataTemplate的GT;
                <复选框器isChecked ={绑定值,模式=单向}/>
            < / DataTemplate中>
        < /地方:Selector.Template1>
        <局部:Selector.Template2>
            <&DataTemplate的GT;
                < TextBlock的文本={绑定值,模式=单向}>
                    < TextBlock.Style>
                        <风格的TargetType ={X:类型的TextBlock}>
                            < setter属性=粗细VALUE =大胆/>
                        < /样式和GT;
                    < /TextBlock.Style>
                < / TextBlock的>
            < / DataTemplate中>
        < /地方:Selector.Template2>
    < /本地:选择>    <! - 为COLUMN2选择CellTemplate基于ROWTYPE(资讯) - GT;
    <局部:选择X:键=infoSelector>
        <局部:Selector.Template1>
            <&DataTemplate的GT;
                <帆布HEIGHT =16>
                    < TextBlock的文本={绑定信息,模式=单向}
                               前景=蓝VerticalAlignment =顶部/>
                < /帆布>
            < / DataTemplate中>
        < /地方:Selector.Template1>
        <局部:Selector.Template2>
            <&DataTemplate的GT;
                <帆布HEIGHT =16>
                    < TextBlock的文本={绑定信息,模式=单向}
                               VerticalAlignment =顶部/>
                < /帆布>
            < / DataTemplate中>
        < /地方:Selector.Template2>
    < /本地:选择>
< /Window.Resources>< ListView控件的ItemsSource ={结合A}>
    < ListView.View>
        <&GridView的GT;
            < GridViewColumn标题=值
                 CellTemplateSelector ={StaticResource的valueSelector}/>
            < GridViewColumn标题=信息WIDTH =0
                 CellTemplateSelector ={StaticResource的infoSelector}/>
        < / GridView的>
    < /ListView.View>
< /&的ListView GT;

这是结果:

不,我写了这个答案基于dymanoid的回答根据给出的信息是准确的。

I'd like to display data in ListView with different rows (different style and different content). But as soon as I try to apply a style (which suppose to change nothing) selection stops working and it's not anymore Vista style.

What am I doing wrong? Perhaps wrong approach?

<ListView ItemsSource="{Binding A}">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="B" DisplayMemberBinding="{Binding B}"/>
            ...
        </GridView>
    </ListView.View>

    <!-- commenting below block will return Vista style back -->
    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListViewItem">
                        <GridViewRowPresenter Content="{TemplateBinding Content}"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListView.ItemContainerStyle>
</ListView>

解决方案

I try to keep it as general as possible so I define a simple enum for different types that each row can take:

public enum RowType { Bool, Int32 }

Now I use it in the view model for row:

public class Row: DependencyObject
{
    //create a new row with the given value
    //automatically set Value, Info and RowType based on the param
    public Row(object val)
    {
        Value = val;
        if (val.GetType() == typeof(bool)) RowType = WpfApplication3.RowType.Bool;
        else RowType = WpfApplication3.RowType.Int32;
        Info = val.ToString() + " of type " +val.GetType().ToString();
    }

    public RowType RowType { get; set; }

    /// <summary>
    /// Gets or sets a bindable value that indicates Value
    /// </summary>
    public object Value
    {
        get { return (object)GetValue(ValueProperty); }
        set { SetValue(ValueProperty, value); }
    }
    public static readonly DependencyProperty ValueProperty =
        DependencyProperty.Register("Value", typeof(object), typeof(Row), new PropertyMetadata(0));

    /// <summary>
    /// Gets or sets a bindable value that indicates Info
    /// </summary>
    public string Info
    {
        get { return (string)GetValue(InfoProperty); }
        set { SetValue(InfoProperty, value); }
    }
    public static readonly DependencyProperty InfoProperty =
        DependencyProperty.Register("Info", typeof(string), typeof(Row), new PropertyMetadata(""));
}

Now that the view model is ready I create a simple TemplateSelector which responds to RowType of the given row:

public class Selector : DataTemplateSelector
{
    //Template for RowType==Bool
    public DataTemplate Template1 { get; set; }
    //Template for RowType==Int32
    public DataTemplate Template2 { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        var row = item as Row;
        if (row == null) return null;

        switch (row.RowType)
        {
            case RowType.Bool:
                return Template1;
            case RowType.Int32:
                return Template2;
            default:
                return null;
        }
    }
}

And I use it in Xaml like this:

<Window.Resources>

    <!-- selects CellTemplate for column1 (Value) based on RowType -->
    <local:Selector x:Key="valueSelector">
        <local:Selector.Template1>
            <DataTemplate>
                <CheckBox IsChecked="{Binding Value, Mode=OneWay}"/>
            </DataTemplate>
        </local:Selector.Template1>
        <local:Selector.Template2>
            <DataTemplate>
                <TextBlock Text="{Binding Value, Mode=OneWay}">
                    <TextBlock.Style>
                        <Style TargetType="{x:Type TextBlock}">
                            <Setter Property="FontWeight" Value="Bold"/>
                        </Style>
                    </TextBlock.Style>
                </TextBlock>
            </DataTemplate>
        </local:Selector.Template2>
    </local:Selector>

    <!-- selects CellTemplate for column2 (Info) based on RowType -->
    <local:Selector x:Key="infoSelector">
        <local:Selector.Template1>
            <DataTemplate>
                <Canvas Height="16">
                    <TextBlock Text="{Binding Info, Mode=OneWay}" 
                               Foreground="Blue" VerticalAlignment="Top"/>
                </Canvas>
            </DataTemplate>
        </local:Selector.Template1>
        <local:Selector.Template2>
            <DataTemplate>
                <Canvas Height="16">
                    <TextBlock Text="{Binding Info, Mode=OneWay}"
                               VerticalAlignment="Top"/>
                </Canvas>
            </DataTemplate>
        </local:Selector.Template2>
    </local:Selector>
</Window.Resources>

<ListView ItemsSource="{Binding A}">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Value" 
                 CellTemplateSelector="{StaticResource valueSelector}"/>
            <GridViewColumn Header="Info" Width="0"
                 CellTemplateSelector="{StaticResource infoSelector}"/>
        </GridView>
    </ListView.View>
</ListView>

This is the result:

Not that I wrote this answer based on dymanoid's answer which is accurate based upon given information.

这篇关于Vista的风格的ListView(GridViewRow presenter)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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