2012-06-15 4 views
1

Я разрешаю пользователю перетаскивать некоторые объекты из панели инструментов, и, конечно, каждый object имеет уникальный идентификатор. Как только объект будет использован, скажем, на grid или canvas, мне нужно показать его свойства, поэтому мне нужен массив объектов, где каждый объект может содержать свои собственные свойства.Сохранение свойств объектов в C#/WPF

Можете ли вы дать мне несколько советов и рекомендаций о том, как реализовать класс для обработки нескольких объектов, в то время как каждый объект может удерживать до 10 свойств?

+0

Необходимо предоставить более подробную информацию о проблеме. –

+0

Похоже, вы хотите Список объектов. Или, возможно, словарь, если вы хотите получить доступ к каждому объекту через его уникальный ключ. – AndrewC

+0

Используйте либо ObservableDictionary внутри классов, либо WPF PropertyGrid. –

ответ

1

Лучшим решением является использование управления PropertyGrid; ваше приложение будет похоже на Visual Studio, и ваша реализация будет похожа на это.

Посмотрите на этот вопрос SO для имеющихся PropertyGrid вариантов у вас есть - Is there a Property Dialog control that i can use in my WPF App?

Теперь вы можете определить класс для каждого элемента управления и объявить нормальные свойства CLR для этого элемента управления; свойства, которые вы не хотите отображать в PropertyGrid, могут быть отмечены BrowsableAttribute, и PropertyGrid будет соблюдать это.

Если вы хотите больше контролировать, какие свойства отображаются, вы можете создать свой собственный attribute и изменить реализацию PropertyGrid, чтобы использовать этот атрибут и свойства отображения, отмеченные этим атрибутом.

+1

Спасибо. да, кажется, это то, что мне нужно. –

+0

@amitkohan Рад, что это помогло. – akjoshi

1

Можете ли вы дать мне несколько советов и направление о том, как реализовать класс для обработки нескольких объектов в то время как каждый объект может держаться скажем 10 свойств?

Вам не нужно вводить такой класс. То, как я буду справляться с этой проблемой, будет иметь общий базовый класс для всех объектов в панели инструментов (например, ToolboxItem), который предоставляет только свойства и функции, общие для всех элементов в панели инструментов.

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

Тогда вы можете получить конкретные товары из этого класса E.G. TextToolboxItem и RectangleToolboxItem (или что угодно). Затем производные классы могут выставлять только те свойства, которые им требуются.

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

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

Чтобы сохранить их, Вы могли бы просто использовать общую коллекцию, таких как:

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

До тех пор, пока элементы вытекают из ToolboxItem все они могут быть проведены в рамках одной коллекции и отдельные свойства могут все быть связанными с использованием функций привязки данных WPF.

Вы можете создавать и выставлять данные следующим образом:

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

Чтобы отобразить эту информацию в пользовательском интерфейсе я сделать следующее:

  • Используйте сетку, чтобы расколоть вид на два раздела.Во-первых, будут отображаться свойства выбранного элемента, а во втором отображается «проектная поверхность»
  • Используйте ContentPresenter для отображения свойств , выбранного.
  • Используйте ListBox с обычным ItemsPanel и ItemContainerStyle, чтобы «нарисовать» ваши предметы на поверхности дизайна.
  • Использовать DataTemplate, чтобы сообщить WPF, как визуализировать каждый элемент как в «сетке свойств», так и в «поверхности дизайна» (This сообщение описывает, как использовать разные DataTemplate для разных объектов).

В XAML, необходимое для достижения этой цели, показан ниже:

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

Конечный результат выглядит следующим образом:

enter image description here

Обратите внимание, что свойства выбранного элемент отображается в левой части окна.

Теперь это решение в настоящее время очень грубо, но демонстрирует отправную точку для вас, чтобы развивать это дальше. Идеи для улучшения включают в себя:

  • Рефакторинг кода в представленииModel, так что он совместим с MVVM.
  • Обработка перетаскивания предметов на «поверхности дизайна».
  • Изменение «ContentPresenter» для сетки свойств, чтобы предоставить вам гораздо более богатую поддержку для отображения и редактирования свойств выбранного объекта.
Смежные вопросы