繁体   English   中英

ItemsControl显示类名

[英]ItemsControl displaying class name

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

首先是我的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));
    }
}

}

我不确定你想要实现什么,但这里有一些我在你的代码中发现的问题。

  1. 您应该将VM直接分配给PageDataContext

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

    完成后,您现在可以从Canvas 删除 DataContext="{Binding Source={StaticResource DrawBoxViewModel}}"

  2. <ItemsControl.Resource>替换为<ItemsControl.ItemTemplate>并删除x:Key="test" ,假设您要在UI上显示多个TextBox 您定义的ResourceDataTemplate在您通过其键引用它之前不会执行任何操作。 我不认为你真的想要这个。
  3. 您应该使用x:Bind来进行XY绑定

     <TranslateTransform X="{x:Bind LeftCanvas}" Y="{x:Bind TopCanvas}" /> 
  4. 您的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 

希望这可以帮助!

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

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

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

这意味着在WPF中,您可以通过数据模板的x:DataType="Object Type"属性将数据模板与类/对象相关联(这就是您所做的)。 绑定集合时,呈现引擎会自动将集合中的各个项目与其各自的模板进行匹配。

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

长话短说 - 将模板移动到页面资源集合。 给它一个关键,如:

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

在items控件中引用模板,如下所示: <ItemsControl ItemsSource="{Binding Boxes} ItemTemplate={StaticResource test} ">

暂无
暂无

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

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