Как создать пользовательский интерфейс для имитации разделов оперативной памяти в WPF? - PullRequest
2 голосов
/ 15 марта 2012

Я занимаюсь разработкой симуляции RAM в WPF.Когда я создаю память, я устанавливаю размер (1024 k) и могу создавать разделы, задавая размер и положение.

Вот классы:

public class Memory
{
    public ObservableCollection<Partition> Partitions { get; set; }
    public ulong Size { get; set; }

    public Memory(ulong size)
    {
        this.Partitions = new ObservableCollection<Partition>();
        this.Size = size;
    }
}

public class Partition
{
    public int Id { get; set; }
    public ulong Size { get; set; }
    public ulong Position { get; set; }
}

public class MemoryService
{
    public Memory GetModel()
    {
        var model = new Memory2(1024);
        model.Partitions.Add(new Partition() { Id = 1, Size = 512, Position = 0 });
        model.Partitions.Add(new Partition() { Id = 2, Size = 256, Position = 512 });
        model.Partitions.Add(new Partition() { Id = 3, Size = 256, Position = 768 });

        return model;
    }
}

Моя проблема в том, как можноЯ показываю эту модель в пользовательский интерфейс?Я планирую создать что-то вроде этого:

enter image description here

Когда я добавляю новый раздел, он должен показывать слева позицию и ширину каждого прямоугольника разделадолжен быть пропорционален размерам (т. е. объем памяти равен 1024, а раздел 1 имеет 512, поэтому этот раздел составляет половину объема памяти в изображении).

На данный момент я не создаллюбой пользовательский интерфейс, но я думаю, мне нужно будет создать новый элемент управления, где я рисую на холсте.Я действительно не уверен в этом, могу ли я немного помочь с тем, как я могу начать?Я действительно понятия не имею, создание новых элементов управления.

Большое спасибо!

1 Ответ

4 голосов
/ 15 марта 2012

WPF (в частности, XAML) сделан для такого рода вещей. ItemsControl с настроенным ItemTemplate может сделать это так элегантно, что нет абсолютно никакой причины создавать собственный элемент управления и рисовать его в коде. Чтобы показать, насколько это просто, я смоделировал простой прототип, используя в основном XAML.

Сначала несколько предварительных изменений в вашей модели памяти. Чтобы упростить вычисление высоты, я добавил свойство RelativeSize в класс Partition. Это именно то, на что это похоже, значение double, которое является результатом Partition.Size / Memory.Size. Это единственное изменение модели, которое я сделал.

Теперь, хорошие вещи:

<Window x:Class="DrawMemory.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:DrawMemory"
    Width="200"
    Height="600"
    Title="Draw Memory">
<Window.Resources>
    <local:MultiplyConverter x:Key="MultiplyConverter"/>
</Window.Resources>

<Grid x:Name="Grid"
      Margin="5">
    <ItemsControl ItemsSource="{Binding Partitions}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition MaxWidth="80"/>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>

                    <TextBlock Text="{Binding Position, StringFormat={}{0}k}"
                               Margin="5"/>
                    <Grid Grid.Column="1">
                        <Border BorderThickness="5"
                                BorderBrush="Black">
                            <Border.Height>
                                <MultiBinding Converter="{StaticResource MultiplyConverter}">
                                    <Binding ElementName="Grid" Path="ActualHeight"/>
                                    <Binding Path="RelativeSize"/>
                                </MultiBinding>
                            </Border.Height>
                        </Border>
                        <TextBlock Text="{Binding Id}"
                                   VerticalAlignment="Center"
                                   HorizontalAlignment="Center"/>
                    </Grid>
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

Я создал простое окно с одним ItemsControl. Предметы, которые он использует, являются разделами, очевидно. Для каждого раздела я создаю Grid с двумя столбцами. В первом столбце я пишу некоторый текст для позиции в памяти (я использовал StringFormat, чтобы добавить «k»). Во втором столбце у меня есть еще один Grid, который состоит из Border и текста из Id.

Единственная логика здесь - в привязке высоты. Здесь я в основном говорю: «свяжите высоту этой границы с высотой родительской сетки, умноженной на относительный размер раздела». Я создал некоторый код для многократного конвертера, но он очень прост (а не качество продукции):

public class MultiplyConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        return (double)values[0] * (double)values[1];
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        return null;
    }
}

Из-за этой привязки при изменении размера Window высота границы будет синхронизироваться. Другими словами, это ItemsControl всегда будет соответствовать доступному пространству. Вот как это выглядит в итоге:

Screenshot of Window

Очевидно, вам нужно много полировать. Но это должно дать вам хорошее представление о том, на что способен XAML.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...