在ListViev UWP中使用UserControl,数据绑定问题

时间:2019-05-10 19:30:04

标签: c# xaml listview data-binding uwp

我想创建一个App来管理各种项目,所以我创建了一个类来代表那些项目。为了显示它们,我创建了一个用户控件,然后将其显示在屏幕上,以后还管理用户和Project-Object之间的交互。 我试图在页面中显示项目列表,但是它不起作用。 我不确定要在数据模板中绑定什么,我尝试过的方法都没有。 我还使用了实时可视化树,并且我认为ProjectViewer的Property Project已正确设置,但Textbok仍不显示项目的名称。 (但是我不太熟悉实时视觉树,所以我可能是错的)。 如果我将用户控件用作单个实例而不是在列表中,则可以设置Project属性,并显示Name。 我认为这是DataBinding的问题,但我无法解决。 任何帮助将不胜感激,因为这只是该应用程序的第一步,而且我已经停滞了。

这是我创建的用于解决该问题的最小示例:

我有一个课程Project:

using System.Collections.Generic;
using Windows.UI.Xaml;

namespace ProjectTimeTracker
{
    public class Project:DependencyObject
    {
        public string ProjName
        {
            get { return (string)GetValue(ProjNameProperty); }
            set { SetValue(ProjNameProperty, value); }
        }
        public static readonly DependencyProperty ProjNameProperty =
                DependencyProperty.Register(nameof(ProjName), typeof(string), typeof(Project), new PropertyMetadata("TestName"));

        public Project(){}
    }
}

然后我创建了UserControl ProjectViewer:

namespace ProjectTimeTracker.UI
{
    public sealed partial class ProjectViewer : UserControl
    {
        public Project Project
        {
            get { return (Project)GetValue(ProjectProperty); }
            set { SetValue(ProjectProperty, value); }
        }
        public static readonly DependencyProperty ProjectProperty =
                DependencyProperty.Register(nameof(Project), typeof(Project), typeof(ProjectViewer), new PropertyMetadata(null));


        public ProjectViewer()
        {
            this.InitializeComponent();
        }
    }
}

具有以下xaml代码:

<UserControl
    x:Class="ProjectTimeTracker.UI.ProjectViewer"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:ProjectTimeTracker.UI"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="100"
    d:DesignWidth="400">

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="38"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <RadioButton x:Name="RBSelector" HorizontalAlignment="Left" Margin="8,0,0,0" VerticalAlignment="Center" Grid.RowSpan="2"/>
        <TextBlock x:Name="TBName" Grid.Row="0" Grid.Column="1" Text="{x:Bind Project.ProjName}" VerticalAlignment="Center" HorizontalAlignment="Left" Style="{ThemeResource TitleTextBlockStyle}" Width="110"/>
        <TextBlock x:Name="TBTotalTime" Grid.Row="1" Grid.Column="1" Text="NYI" HorizontalAlignment="Left" VerticalAlignment="Center" Style="{ThemeResource CaptionTextBlockStyle}" Margin="0,-4,0,0"/>

    </Grid>
</UserControl>

我尝试在主页中使用该用户控件来创建项目列表

using System.Collections.Generic;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace ProjectTimeTracker
{
    public sealed partial class MainPage : Page
    {
        public List<Project> Projects
        {
            get { return (List<Project>)GetValue(ProjectsProperty); }
            set { SetValue(ProjectsProperty, value); }
        }
        public static readonly DependencyProperty ProjectsProperty =
                DependencyProperty.Register(nameof(Projects), typeof(List<Project>), typeof(MainPage), new PropertyMetadata(new List<Project>()));


        public MainPage()
        {
            this.InitializeComponent();

            Projects.Add(new Project() { ProjName="Projekt1"});
            list.ItemsSource = Projects;
        }
    }
}

xaml看起来像这样:

<Page xmlns:UI="using:ProjectTimeTracker.UI" 
    x:Class="ProjectTimeTracker.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:ProjectTimeTracker"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid>
        <ListView x:Name="list"  HorizontalAlignment="Center" VerticalAlignment="Center">
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="local:Project">
                    <UI:ProjectViewer Project="{x:Bind }"/>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</Page>

1 个答案:

答案 0 :(得分:1)

  

在ListViev UWP中使用UserControl,数据绑定问题

我已经修改了您的代码,请参考以下内容

ProjectViewer.xaml.cs

public sealed partial class ProjectViewer : UserControl
{
    public ProjectViewer()
    {
        this.InitializeComponent();
    }

    public Project ProjectSource
    {
        get { return (Project)GetValue(ProjectSourceProperty); }
        set { SetValue(ProjectSourceProperty, value); }
    }

    public static readonly DependencyProperty ProjectSourceProperty =
        DependencyProperty.Register("ProjectSource", typeof(Project), typeof(ProjectViewer), new PropertyMetadata(0, new PropertyChangedCallback(CallBack)));

    private static void CallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var current = d as ProjectViewer;
        if (e.NewValue != e.OldValue)
        {
            current.TBName.Text = (e.NewValue as Project).ProjName;
        }
    }
}

public class Project
{
    public string ProjName { get; set; }

    public Project()
    {
    }
}

ProjectViewer.xaml

                                                                         

<RadioButton
    x:Name="RBSelector"
    Grid.RowSpan="2"
    Margin="8,0,0,0"
    HorizontalAlignment="Left"
    VerticalAlignment="Center"
    />
<TextBlock
    x:Name="TBName"
    Grid.Row="0"
    Grid.Column="1"
    Width="110"
    HorizontalAlignment="Left"
    VerticalAlignment="Center"
    Style="{ThemeResource TitleTextBlockStyle}"      
    />
<TextBlock
    x:Name="TBTotalTime"
    Grid.Row="1"
    Grid.Column="1"
    Margin="0,-4,0,0"
    HorizontalAlignment="Left"
    VerticalAlignment="Center"
    Style="{ThemeResource CaptionTextBlockStyle}"
    Text="NYI"
    />

用法

public sealed partial class MainPage : Page
{
    public List<Project> Projects = new List<Project>();
    public MainPage()
    {
        this.InitializeComponent();     

        Projects.Add(new Project() { ProjName = "Projekt1" });       
        list.ItemsSource = Projects;
    }
    public string TestString { get; set; }
}

Xaml

<ListView
    x:Name="list"
    HorizontalAlignment="Center"
    VerticalAlignment="Center"
    >
    <ListView.ItemTemplate>
        <DataTemplate >
            <local:ProjectViewer ProjectSource="{Binding }" />
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>