Можете ли вы дать мне несколько советов и направление о том, как реализовать класс для обработки нескольких объектов в то время как каждый объект может держаться скажем 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>
Конечный результат выглядит следующим образом:
Обратите внимание, что свойства выбранного элемент отображается в левой части окна.
Теперь это решение в настоящее время очень грубо, но демонстрирует отправную точку для вас, чтобы развивать это дальше. Идеи для улучшения включают в себя:
- Рефакторинг кода в представленииModel, так что он совместим с MVVM.
- Обработка перетаскивания предметов на «поверхности дизайна».
- Изменение «ContentPresenter» для сетки свойств, чтобы предоставить вам гораздо более богатую поддержку для отображения и редактирования свойств выбранного объекта.
Необходимо предоставить более подробную информацию о проблеме. –
Похоже, вы хотите Список объектов. Или, возможно, словарь, если вы хотите получить доступ к каждому объекту через его уникальный ключ. – AndrewC
Используйте либо ObservableDictionary внутри классов, либо WPF PropertyGrid. –