ItemsControl显示类名

时间:2017-08-25 21:09:37

标签: c# uwp uwp-xaml

此应用根据需要显示集合的类名而不是文本框。我已经阅读了其他相关问题,但无法弄清楚我错过了什么。我有一个datacontext,我作为itemource绑定到集合,并且我添加了一个项目。我想要的只是绑定集合' Boxes'在我的视图模型' DrawBoxViewModel'到项目源,并让它显示单个项目作为文本框。所有帮助表示赞赏。

首先是我的XAML:

<Page
x:Class="BoxMaker2.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:BoxMaker2"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:BoxMaker2.ViewModels"
mc:Ignorable="d">

<Page.Resources>
    <vm:DrawBoxViewModel x:Key="DrawBoxViewModel"/>
</Page.Resources>
<Canvas DataContext="{Binding Source={StaticResource DrawBoxViewModel}}">
    <ItemsControl ItemsSource="{Binding Boxes}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas Width="350" Height="600" Background="AliceBlue"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.Resources>
            <DataTemplate x:DataType="vm:Box" x:Key="test">
                <VariableSizedWrapGrid>
                    <TextBox Background="White" 
                             Text="{x:Bind Data}"
                             Width="100"
                             Height="100"/>
                    <VariableSizedWrapGrid.RenderTransform>
                        <TranslateTransform X="{Binding LeftCanvas}" Y="{Binding TopCanvas}"/>
                    </VariableSizedWrapGrid.RenderTransform>
                </VariableSizedWrapGrid>
            </DataTemplate>
        </ItemsControl.Resources>
    </ItemsControl>
</Canvas>

现在我的viewmodel:

namespace BoxMaker2.ViewModels
{
public class DrawBoxViewModel
{
    #region fields

    private ObservableCollection<Box> _boxes;

    #endregion

    #region properties

    public ObservableCollection<Box> Boxes { get { return this._boxes; } }

    #endregion

    #region constructors

    public DrawBoxViewModel()
    {
        this._boxes = new ObservableCollection<Box>();
        _boxes.Add(new Box() { Data = "hello!", LeftCanvas = 200, TopCanvas = 200 });
    }

    #endregion

}

public class Box : INotifyPropertyChanged
{
    private int _generation;
    public int Generation
    {
        get { return _generation; }
        set { _generation = value; OnPropertyChanged("Generation"); }
    }

    private int _childNo;
    public int ChildNo
    {
        get { return _childNo; }
        set { _childNo = value; OnPropertyChanged("ChildNo"); }
    }

    private Box _parentBox;
    public Box ParentBox
    {
        get { return _parentBox; }
        set { _parentBox = value; OnPropertyChanged("ParentBox"); }
    }

    private List<Box> _childrenBox;
    public List<Box> ChildrenBox
    {
        get { return _childrenBox; }
        set { _childrenBox = value; OnPropertyChanged("ChildrenBox"); }
    }

    private string _data;
    public string Data
    {
        get { return _data; }
        set
        {
            _data = value;
            OnPropertyChanged("Data");
        }
    }

    private double _topCanvas;
    public double TopCanvas
    {
        get { return _topCanvas; }
        set
        {
            _topCanvas = value;
            OnPropertyChanged("TopCanvas");
        }
    }

    private double _leftCanvas;
    public double LeftCanvas
    {
        get { return _leftCanvas; }
        set
        {
            _leftCanvas = value;
            OnPropertyChanged("LeftCanvas");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

}

2 个答案:

答案 0 :(得分:2)

我不确定您要实现的目标,但我在您的代码中发现了一些问题。

  1. 您应该将VM分配到DataContext的{​​{1}} 直接

    Page

    完成此操作后,您现在可以从<Page.DataContext> <vm:DrawBoxViewModel /> </Page.DataContext> 删除 DataContext="{Binding Source={StaticResource DrawBoxViewModel}}"

  2. Canvas替换为 <ItemsControl.Resource>并删除<ItemsControl.ItemTemplate>,假设您要显示多个 用户界面x:Key="test"TextBox你内的DataTemplate 在您通过其键引用它之前,定义将不会执行任何操作。我不 以为你真的想要这个。
  3. 您应该Resource使用x:Bind&amp; X绑定

    Y
  4. 您的<TranslateTransform X="{x:Bind LeftCanvas}" Y="{x:Bind TopCanvas}" /> 集合可以简化为以下

    Boxes
  5. 希望这有帮助!

答案 1 :(得分:1)

您的Items控件不知道要使用哪个数据模板。目前,您的视图模型具有通过x:DataType="vm:Box"与其关联的模板,x:DataType="Object Type"被定义为项目控件中的资源。

问题是Universal Windows Platform无法识别与数据类型关联的模板。因此,即使有一个模板,控件在渲染视图模型集合时也不知道如何找到它。

基于绑定类型自动解析模板是WPF的一个功能,在UWP中不可用。

这意味着在WPF中,您可以通过数据模板的<Page.Resources> <vm:DrawBoxViewModel x:Key="DrawBoxViewModel"/> <DataTemplate x:Key="test"> <VariableSizedWrapGrid> <TextBox Background="White" Text="{x:Bind Data}" Width="100" Height="100"/> <VariableSizedWrapGrid.RenderTransform> <TranslateTransform X="{Binding LeftCanvas}" Y="{Binding TopCanvas}"/> </VariableSizedWrapGrid.RenderTransform> </VariableSizedWrapGrid> </DataTemplate> </Page.Resources> 属性将数据模板与类/对象相关联(这就是您所做的)。绑定集合时,呈现引擎会自动将集合中的各个项目与其各自的模板进行匹配。

这非常强大,因为如果您的集合有许多不同类型的框(或者从DrawBoxViewModel继承的东西),您可以通过简单地定义模板来不同地呈现每个项目类型。那不过了。微软在UWP中销毁了该功能。

这么长的故事简短 - 将模板移动到页面资源集合。给它一个关键,如:

<ItemsControl ItemsSource="{Binding Boxes} ItemTemplate={StaticResource test} ">

在项目控件中引用模板,如下所示: ListFTP