简体   繁体   English

ItemsControl显示类名

[英]ItemsControl displaying class name

This app is displaying the class name of a collection instead of a text-box as desired. 此应用程序根据需要显示集合的类名而不是文本框。 I've read other issues with this, but cannot figure out what I'm missing. 我已经阅读了其他问题,但无法弄清楚我错过了什么。 I have a datacontext, I'm bound to the collection as an itemsource, and I've added a single item. 我有一个datacontext,我将这个集合绑定为itemource,并且我添加了一个项目。 All I want is to bind the collection 'Boxes' in my view model 'DrawBoxViewModel' to an item source, and have it display a single item as a text box. 我想要的是将我的视图模型'DrawBoxViewModel'中的集合'Boxes'绑定到项目源,并让它将单个项目显示为文本框。 All help is appreciated. 所有帮助表示赞赏。

First my XAML: 首先是我的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>

And now my viewmodel: 现在我的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));
    }
}

} }

I am not exactly sure what you are trying to achieve but here's a few issues I have found in your code. 我不确定你想要实现什么,但这里有一些我在你的代码中发现的问题。

  1. You should assign your VM to the DataContext of the Page directly. 您应该将VM直接分配给PageDataContext

     <Page.DataContext> <vm:DrawBoxViewModel /> </Page.DataContext> 

    After doing so, you can now remove DataContext="{Binding Source={StaticResource DrawBoxViewModel}}" from your Canvas . 完成后,您现在可以从Canvas 删除 DataContext="{Binding Source={StaticResource DrawBoxViewModel}}"

  2. Replace <ItemsControl.Resource> with <ItemsControl.ItemTemplate> and remove x:Key="test" , assuming you want to show multiple TextBox es on the UI. <ItemsControl.Resource>替换为<ItemsControl.ItemTemplate>并删除x:Key="test" ,假设您要在UI上显示多个TextBox The DataTemplate within the Resource you defined won't do anything until you reference it by its key. 您定义的ResourceDataTemplate在您通过其键引用它之前不会执行任何操作。 I don't think you really want that here though. 我不认为你真的想要这个。
  3. You should use x:Bind for your X & Y binding 您应该使用x:Bind来进行XY绑定

     <TranslateTransform X="{x:Bind LeftCanvas}" Y="{x:Bind TopCanvas}" /> 
  4. Your Boxes collection can be simplified as following 您的Boxes集合可以简化如下

     #region properties public ObservableCollection<Box> Boxes { get; } = new ObservableCollection<Box>(); #endregion #region constructors public DrawBoxViewModel() { Boxes.Add(new Box() { Data = "hello!", LeftCanvas = 0, TopCanvas = 200 }); } #endregion 

Hope this helps! 希望这可以帮助!

Your Items control doesn't know which data template to use. 您的Items控件不知道要使用哪个数据模板。 Currently your view model has a template associated to it via the x:DataType="vm:Box" which is defined as a resource in the items control. 目前,您的视图模型具有通过x:DataType="vm:Box"与其关联的模板,该模板被定义为items控件中的资源。

The problem is that Universal Windows Platform doesn't recognize templates associated to data types. 问题是Universal Windows Platform无法识别与数据类型关联的模板。 So even though there is a template, the control doesn't know how to find it when it is rendering the collection of view models. 因此,即使存在模板,控件也不知道在渲染视图模型集合时如何找到它。

Automatic resolving of templates based on bound types was a function of WPF which is not available in UWP. 基于绑定类型自动解析模板是WPF的一个功能,在UWP中不可用。

What that means is that in WPF you could associate a data template to a class/object via the x:DataType="Object Type" attribute of the data template (which is what you did). 这意味着在WPF中,您可以通过数据模板的x:DataType="Object Type"属性将数据模板与类/对象相关联(这就是您所做的)。 When the collection is bound, the rendering engine would auto-magically match the the individual items in the collection to their respective templates. 绑定集合时,呈现引擎会自动将集合中的各个项目与其各自的模板进行匹配。

This was very powerful because if your collection had many different types of boxes for example (or things inheriting from DrawBoxViewModel) you could render each item type differently by simply defining a template. 这非常强大,因为如果您的集合有许多不同类型的框(或者从DrawBoxViewModel继承的东西),您可以通过简单地定义模板来呈现不同的项类型。 Well this is no more. 那不过了。 Microsoft destroyed that feature in UWP. 微软在UWP中销毁了该功能。

So long story short - move the template to the page resource collection. 长话短说 - 将模板移动到页面资源集合。 Give it a key such as: 给它一个关键,如:

<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>

Reference the template in your items control as follows: <ItemsControl ItemsSource="{Binding Boxes} ItemTemplate={StaticResource test} "> 在items控件中引用模板,如下所示: <ItemsControl ItemsSource="{Binding Boxes} ItemTemplate={StaticResource test} ">

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM