在C#中存储对象的属性/ WPF [英] Storing properties of objects in C#/WPF

查看:239
本文介绍了在C#中存储对象的属性/ WPF的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我允许用户拖动/每个对象都有一个唯一的ID,当然工具箱和删除某些对象。当对象被使用,比方说放置在电网画布,我需要证明其属性,所以我需要对象,每个对象都可以保持其自己的属性的数组。

您可以给我如何实现一个类来处理多个对象的一些建议和方向,而每一个对象都可以坚持到让我们说10属性?

解决方案
  

您可以给我如何实现一个类中的一些建议和指导   处理多个对象,而每一个对象都可以坚持到让我们说   10属性?

有没有必要为你实现这样的类。该方式,我会处理这个问题将是对工具箱(的ToolboxItem )后,只有公开的属性和功能通用于所有项目中的所有对象的公共基类在工具箱中。

 公共抽象类的ToolboxItem
{
    公共字符串名称{;组; }
    公共点位置{获得;组; }
}
 

您可以再从这个类EG得到您的具体项目 TextToolboxItem RectangleToolboxItem (或任何你想要的)。然后,派生类可以只暴露他们需要的属性。

 公共类TextToolboxItem:的ToolboxItem
{
    公共字符串文本{获得;组; }
}

公共类RectangleToolboxItem:的ToolboxItem
{
    公共矩形边界{获得;组; }
}
 

要存储这些你可以只使用一个泛型集合,如:

 的ObservableCollection<的ToolboxItem>项目=新的ObservableCollection< ToolboxItems>();
 

只要项目从的ToolboxItem 导出他们都可以在单个集合内举行,各个属性都可以绑定到使用WPF的数据绑定功能。

您可以再创建和公开数据以下列方式:

 公共部分类主窗口:窗口
{
    私人的ObservableCollection<的ToolboxItem>项目;

    公共主窗口()
    {
        的InitializeComponent();
        this.DataContext =这一点;

        项目=新的ObservableCollection<的ToolboxItem>
        {
            新TextToolboxItem {名称=primaryText
                                  文字=世界,你好,
                                  位置=新的点(40,130)},
            新TextToolboxItem {名称=secondaryText
                                  文字=世界,你好(又),
                                  位置=新的点(200,30)},
            新RectangleToolboxItem {位置=新的点(50300),
                                       NAME =Rect1的,
                                       边界=新的Rect(0,0,150,85)},
        };
    }

    公众的ObservableCollection<的ToolboxItem>项目{{返回的物品; }}
}
 

要显示此信息在用户界面上我会做到以下几点:

  • 使用网格的视图分为两个部分。第一种情况是所选项目的属性将显示第二显示设计图面
  • 使用一个内容presenter 显示在选择项目的属性。
  • 使用一个列表框用自定义的 ItemsPanel ItemContainerStyle 为'画'您的项目到设计界面。
  • 使用一个的DataTemplate 来告诉WPF如何呈现在两个属性网格和设计图面'(的This 文章描述了如何使用不同的的DataTemplate 针对不同的对象)。

要实现这一目标所需的XAML如下:

 <窗​​口x:类=WpfApplication1.MainWindow
    的xmlns =htt​​p://schemas.microsoft.com/winfx/2006/xaml/$p$psentation
    的xmlns:X =htt​​p://schemas.microsoft.com/winfx/2006/xaml
    的xmlns:此=CLR的命名空间:WpfApplication1
    标题=主窗口高度=350宽度=525>
<电网>
    < Grid.ColumnDefinitions>
        < ColumnDefinition WIDTH =3 */>
        < ColumnDefinition宽度=7 */>
    < /Grid.ColumnDefinitions>

    <内容presenter CONTENT ={结合的ElementName =列表框,路径=的SelectedItem}
                      保证金=5>
        <内容presenter.Resources>
            < D​​ataTemplate中数据类型={X:输入:TextToolboxItem}>
                < StackPanel的>
                    < TextBlock的文本={结合名}/>
                    < TextBlock的文本={结合位置}/>
                    < TextBlock的文本={结合文字}/>
                < / StackPanel的>
            < / DataTemplate中>
            < D​​ataTemplate中数据类型={X:输入:RectangleToolboxItem}>
                < StackPanel的>
                    < TextBlock的文本={结合名}/>
                    < TextBlock的文本={结合位置}/>
                    < TextBlock的文本={结合边界}/>
                < / StackPanel的>
            < / DataTemplate中>
        < /Content$p$psenter.Resources>
    < /内容presenter>

    < ListBox的X:名称=列表框Grid.Column =1
             保证金=5的ItemsSource ={绑定表项}>
        < ListBox.Resources>
            < D​​ataTemplate中数据类型={X:输入:TextToolboxItem}>
                <文本框文本={结合文字}
                         保证金=10/>
            < / DataTemplate中>
            < D​​ataTemplate中数据类型={X:输入:RectangleToolboxItem}>
                <矩形宽度={结合Bounds.Width}
                           身高={结合Bounds.Height}
                           行程=DarkRed填充=粉红/>
            < / DataTemplate中>
        < /ListBox.Resources>

        < ListBox.ItemContainerStyle>
            <样式和GT;
                < setter属性=Canvas.LeftVALUE ={结合Position.X}/>
                < setter属性=Canvas.TopVALUE ={结合Position.Y}/>
            < /样式和GT;
        < /ListBox.ItemContainerStyle>

        < ListBox.ItemsPanel>
            < ItemsPanelTemplate>
                <帆布/>
            < / ItemsPanelTemplate>
        < /ListBox.ItemsPanel>
    < /列表框>

< /网格>
 

最后的结果是这样的:

注意,所选项目的特性示于窗口的左手部分

现在该解决方案是目前非常粗糙,但确实说明一个起点,为您进一步发展这一点。改进意见包括:

  • 重新融通code到一个视图模型,使其MVVM兼容。
  • 处理拖放的项目上的设计图面。
  • 更改'内容presenter'的属性网格给你用来显示和编辑所选对象的属性更丰富的支持。

I'm allowing user to drag/drop some objects from a toolbox and of course each object has a unique id. As soon as object is used, let's say placed on a grid or canvas, I need to show its properties so I need an array of objects where each object can hold its own properties.

Can you give me some advice and direction on how to implement a class to handle multiple objects while each object can hold on to let's say 10 properties?

解决方案

Can you give me some advice and direction on how to implement a class to handle multiple objects while each object can hold on to let's say 10 properties?

There is no need for you to implement such a class. The way I would handle this problem would be to have a common base class for all the objects in the toolbox (ToolboxItem for example) which only exposes properties and functionality common to all items in the toolbox.

public abstract class ToolboxItem
{
    public string Name { get; set; }
    public Point Position { get; set; }
}

You can then derive your specific items from this class E.G. TextToolboxItem and RectangleToolboxItem (or whatever you want). The derived classes can then expose only the properties they require.

public class TextToolboxItem : ToolboxItem
{
    public string Text { get; set; }
}

public class RectangleToolboxItem : ToolboxItem
{
    public Rect Bounds { get; set; }
}

To store these you could just use a generic collection such as:

ObservableCollection<ToolboxItem> items = new ObservableCollection<ToolboxItems>();

As long as the items derive from ToolboxItem they can all be held within the single collection and the individual properties can all be bound to using WPF's data binding features.

You can then create and expose the data in the following way:

public partial class MainWindow : Window
{
    private ObservableCollection<ToolboxItem> items;

    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;

        items = new ObservableCollection<ToolboxItem>
        {
            new TextToolboxItem { Name = "primaryText", 
                                  Text = "Hello world", 
                                  Position = new Point(40, 130) },
            new TextToolboxItem { Name = "secondaryText", 
                                  Text = "Hello world (again)", 
                                  Position = new Point(200, 30) },
            new RectangleToolboxItem { Position = new Point(50,300), 
                                       Name = "Rect1", 
                                       Bounds = new Rect(0, 0, 150, 85) },
        };
    }

    public ObservableCollection<ToolboxItem> Items { get { return items; } }
}

To display this information in the user interface I would do the following:

  • Use a grid to split the view into two sections. The first is where the properties of the selected item will be displayed and the second displays the 'design surface'
  • Use a ContentPresenter to display the properties of the selected item.
  • Use a ListBox with a custom ItemsPanel and ItemContainerStyle to 'draw' your items onto the design surface.
  • Use a DataTemplate to tell WPF how to render each item in both the 'property grid' and the 'design surface' (This post describes how to use a different DataTemplate for different objects).

The xaml required to achieve this is shown below:

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:this="clr-namespace:WpfApplication1"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="3*" />
        <ColumnDefinition Width="7*" />
    </Grid.ColumnDefinitions>

    <ContentPresenter Content="{Binding ElementName=listBox, Path=SelectedItem}"
                      Margin="5">
        <ContentPresenter.Resources>
            <DataTemplate DataType="{x:Type this:TextToolboxItem}">
                <StackPanel>
                    <TextBlock Text="{Binding Name}"/>
                    <TextBlock Text="{Binding Position}"/>
                    <TextBlock Text="{Binding Text}"/>
                </StackPanel>
            </DataTemplate>
            <DataTemplate DataType="{x:Type this:RectangleToolboxItem}">
                <StackPanel>
                    <TextBlock Text="{Binding Name}"/>
                    <TextBlock Text="{Binding Position}"/>
                    <TextBlock Text="{Binding Bounds}"/>
                </StackPanel>
            </DataTemplate>
        </ContentPresenter.Resources>
    </ContentPresenter>

    <ListBox x:Name="listBox" Grid.Column="1"
             Margin="5" ItemsSource="{Binding Items}">
        <ListBox.Resources>
            <DataTemplate DataType="{x:Type this:TextToolboxItem}">
                <TextBox Text="{Binding Text}"
                         Margin="10"/>
            </DataTemplate>
            <DataTemplate DataType="{x:Type this:RectangleToolboxItem}">
                <Rectangle Width="{Binding Bounds.Width}"
                           Height="{Binding Bounds.Height}"
                           Stroke="DarkRed" Fill="Pink"/>
            </DataTemplate>
        </ListBox.Resources>

        <ListBox.ItemContainerStyle>
            <Style>
                <Setter Property="Canvas.Left" Value="{Binding Position.X}"/>
                <Setter Property="Canvas.Top" Value="{Binding Position.Y}"/>
            </Style>
        </ListBox.ItemContainerStyle>

        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas />
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
    </ListBox>

</Grid>

The end result looks like this:

Notice that the properties of the selected item are shown in the left hand section of the window.

Now this solution is currently very crude but does demonstrate a starting point for you to develop this further. Ideas for improvement include:

  • Re-factoring the code into a viewModel so that it is MVVM compliant.
  • Handling drag and drop of the items on the 'design surface'.
  • Changing the `ContentPresenter' for a property grid to give you much richer support for displaying and editing the properties of the selected object.

这篇关于在C#中存储对象的属性/ WPF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆