如何将数据收集与自定义模板绑定

时间:2014-03-08 16:19:31

标签: c# wpf xaml custom-controls

我想避免滚动ListView的{​​{1}},所以我为List创建了自定义控件,其中包含两行网格(第一行是标题,第二行是我可以放置的Header,但我已成功将标题绑定到控件,但我不能对数据执行相同操作。

我的ListView课程:

ListViewCustomControl

我的控制风格:

   public sealed class ListViewCustomControl : Control
    {
        public static readonly DependencyProperty HeaderProperty =
            DependencyProperty.Register(
            "Header", typeof(string), typeof(ListViewCustomControl),
            new PropertyMetadata("custom_template_row1"));

        public static readonly DependencyProperty ElementsSourceProperty =
            DependencyProperty.Register(
            "ElementsSource", typeof(IObservable<Type>), typeof(ListViewCustomControl),
            null);


        public ListViewCustomControl()
        {
            DefaultStyleKey = typeof(ListViewCustomControl);
        }

        public string Header
        {
            get { return (string)GetValue(HeaderProperty); }
            set { SetValue(HeaderProperty, value); }
        }

        public IObservable<Type> ElementsSource
        {
            get { return (IObservable<Type>)GetValue(ElementsSourceProperty); }
            set { SetValue(ElementsSourceProperty, value); }
        }
    }

在xaml文件中使用的示例:

<Style TargetType="local:ListViewCustomControl">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:ListViewCustomControl">
                <Grid Background="BlueViolet">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*"></RowDefinition>
                        <RowDefinition Height="*"></RowDefinition>
                    </Grid.RowDefinitions>
                    <TextBlock Text="{TemplateBinding Header}"></TextBlock>
                    <ListView Grid.Row="1"
                              ItemsSource="{TemplateBinding ElementsSource}">
                        <ListView.ItemTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding TypeVar}"></TextBlock>
                            </DataTemplate>
                        </ListView.ItemTemplate>
                    </ListView>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

发送了数据和 <local:ListViewCustomControl Header="yolo" ElementsSource="{Binding data}"> </local:ListViewCustomControl> 定义

Type

正如我在开头提到的那样。 Header属性运行良好,但我也无法使数据绑定运行良好...

更新

我在调试器中注意到,private void navigationHelper_LoadState(object sender, LoadStateEventArgs e) { var data = new List<Type>(); for (var i = 0; i < 123; i++) data.Add(new Type(i)); defaultViewModel["data"] = data; } public class Type { public int TypeVar { get; set; } public Type(int i) { TypeVar = i; } } 的{​​{1}}函数已被调用一次,仅用于设置SetValue值。

更新

我已将XamlTypeInfo.g.cs更改为Header以及更重要的默认值IObservable并且它适用于默认值,但我仍然无法更改此值... < / p>

IList

1 个答案:

答案 0 :(得分:2)

尝试更改类型ElementsSource

IObservable<>

为:

IList<>
像这样:

public static readonly DependencyProperty ElementsSourceProperty =
        DependencyProperty.Register(
        "ElementsSource", typeof(IList<Type>), typeof(ListViewCustomControl),
        null);

public IList<Type> ElementsSource
{
    get { return (IList<Type>)GetValue(ElementsSourceProperty); }
    set { SetValue(ElementsSourceProperty, value); }
}

对于测试,请尝试设置ListView名称并在代码隐藏中写下此行:

MyListView.ElementsSource = data;

<强> Version with Binding

在这种情况下,您必须指定DataContext,您希望我们列出:

XAML

<local:ListViewCustomControl Header="yolo"
                             ElementsSource="{Binding TestList}" />

Code-behind

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        var testData = new TestData();
        testData.TestList = new List<Type>();

        for (var i = 0; i < 123; i++)
            testData.TestList.Add(new Type(i));

        this.DataContext = testData;
    }
}

public class TestData 
{
    public List<Type> TestList
    {
        get; 
        set; 
    }
}

<强> Some notes

  • 您可以选择IEnumerable的类型,因为它是所有集合的基类。

  • 创建依赖项属性时,可以跳过PropertyMetadata,在这种情况下,系统会自动为此类型指定默认值。