Новое в WPF - какой элемент управления использовать / с чего начать? - PullRequest
1 голос
/ 13 октября 2009

Я WPF n0ob, и я борюсь с выбором соответствующего элемента управления, чтобы получить макет, который я хочу.

То, что я пытаюсь сделать, это нарисовать на экране кучу квадратов (виртуальных заметок). Каждая заметка будет иметь приличный размер (~ 150 пикселей или около того), и таких заметок может быть несколько сотен. Я хочу, чтобы все это можно было прокручивать, чтобы вы могли изменять размеры окна так, как вам нравится, и все это должно быть масштабируемым.

Я сделал это, и это работает.
Но то, что я сделал, кажется ужасно неправильным ...

В коде я динамически создаю заметки к заметкам и добавляю их в гигантский холст. Я вручную делаю математику, чтобы определить, где разместить каждую заметку и насколько большим должен быть холст. Я добавил несколько меток вверху, и мне пришлось вернуться назад и добавить значение «Y Offset», чтобы сдвинуть все квадраты вниз. Я на самом деле генерирую три разных элемента управления canvas и затем добавляю каждый из них на панель стека, которая находится внутри ScrollViewer. Я добавил полосу прокрутки и установил панель стека для увеличения и уменьшения масштаба при настройке панели.

Это «работает», но я чувствую, что на самом деле я не использую WPF так, как он предназначен для использования. Я пытался добиться того же с помощью сетки, но сетка, похоже, не хотела подходить по размеру.

Может кто-нибудь сказать мне «лучший» способ добиться того же внешнего вида?

Вот мой код Xaml - как вы можете видеть; тут не так много ...

<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid x:Name="LayoutRoot">
    <Grid.RowDefinitions>
        <RowDefinition Height="25" />
        <RowDefinition />
    </Grid.RowDefinitions>
    <Slider x:Name="ZoomSlider" Minimum="0.01" Value="1" Maximum="2" Margin="0,0,0,6" />
    <ScrollViewer x:Name="MyScroller" Grid.Row="1" HorizontalScrollBarVisibility="Visible"  HorizontalContentAlignment="Center" VerticalContentAlignment="Center">
        <StackPanel x:Name="TicketsGrid"  Background="White" HorizontalAlignment="Center">

        </StackPanel>
    </ScrollViewer>
</Grid>            

И вот что я делаю в коде (некрасиво !!!)

For Each myWorkItem As WorkItem In myWorkItems
        Dim newRect As New Border

        newRect.Width = TicketSizeX
        newRect.Height = TicketSizeY

        If myWorkItem.State.ToUpper.Contains("HOLD") Then
            newRect.Background = New SolidColorBrush(Colors.Purple)
        Else
            newRect.Background = New SolidColorBrush(Color)
        End If

        newRect.CornerRadius = New System.Windows.CornerRadius(5)
        newRect.BorderThickness = New System.Windows.Thickness(1)
        newRect.BorderBrush = New SolidColorBrush(Colors.Black)

        Dim myPanel As New StackPanel
        newRect.Child = myPanel

        Dim lblTitle As New Label
        lblTitle.Content = myWorkItem.Id
        lblTitle.FontWeight = System.Windows.FontWeights.Bold

        Dim lblDesc As New TextBlock
        lblDesc.Text = myWorkItem.Title
        lblDesc.TextWrapping = TextWrapping.Wrap


        myPanel.Children.Add(lblTitle)
        myPanel.Children.Add(lblDesc)

        newRect.SetValue(Canvas.LeftProperty, CType(((TicketCount Mod TicketsXPerUser) * TicketStepX) + (xOffset * TicketStepX * TicketsXPerUser), Double))
        newRect.SetValue(Canvas.TopProperty, CType(((Math.Floor((TicketCount / TicketsXPerUser)) * TicketStepY)) + NameLabelHeight, Double))

        myCanvas.Children.Add(newRect)
        TicketCount += 1
    Next

    MyCanvas.Width = (TicketStepX * TicketsXPerUser) * myTFS.SharedCodeTeam.Count
    MyCanvas.Height = (CType(((Math.Floor((MaxTicket / TicketsXPerUser)) + 1) * TicketStepY), Double))

    TicketsGrid.Children.Add(MyCanvas)

1 Ответ

6 голосов
/ 13 октября 2009
  1. ScrollViewer с ItemsControl внутри.
  2. Свяжите ItemsSource свойства ItemsControl с ObservableCollection <<em> PostIt > (где PostIt равно простой старый объект CLR со всей информацией, которая отправляется на него).
  3. Добавление DataTemplate к ItemsTemplate свойства ItemsControl
  4. Добавить элементы управления в DataTemplate и привязать их непосредственно к экземпляру PostIt
  5. Добавьте PostIt экземпляров к ObservableCollection <<em> PostIt > в вашем коде.

ScrollViewer обрабатывает всю прокрутку. Это все, что вам нужно.

ItemsControl предназначен для связывания с коллекцией. Для каждого экземпляра в коллекции он выясняет, какой DataTemplate использовать, создает копию шаблона, задает для DataContext корня экземпляр, который он извлек из коллекции, и добавляет шаблон к себе. Это делается для каждого экземпляра, найденного в коллекции.

В вашем коде все, что вам нужно сделать, это создать группу PostIts и добавить их в коллекцию. Никаких чертовых конструкций элементов пользовательского интерфейса, как вы делаете. Urgh.

Если вы можете понять эту концепцию, вы в шаге от понимания MVVM , шаблона Model-View-Controller в WPF. Прочитайте об этом, попробуйте. Это очень простой способ создания очень сложных приложений со сложным пользовательским интерфейсом, но с минимумом кода (и ни одной из тех дерьмов, которые вы делаете в настоящее время).

...