简体   繁体   中英

Using WPF/XAML to add dynamic controls to a form

I'm new to XAML/Wpf forms so maybe this project is a little outside of my ability. I would like to make a scheduler that essentially adds a bunch of "Jobs" to the form, each one has it's own abilities like click events and such but for the most part they are labels with a background and a set size.

Here is something like what I would like that I had made (with data removed) in Winforms, but it was very slow to add to the form. I was hoping some sort of databinding and user controls with xaml would help me out.

我希望调度程序如何工作

There will be a large number of these jobs, ideally I was thinking each row could be it's own usercontrol or each section (marked here as assembly cell).

I had some code that was able to place jobs onto the window, but there was no user control and no row or section labels. It looked like this in the xaml:

<Window.Resources>
    <DataTemplate x:Key="Job">
            <Label Content="{Binding}" Height ="100" Width="100" BorderThickness="1" BorderBrush="Black"/>
        </DataTemplate>
    <DataTemplate x:Key="wrkCenterPanel">
        <ItemsControl ItemsSource="{Binding}" ItemTemplate="{DynamicResource job}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Vertical" Width="Auto" Height="Auto" >

                    </StackPanel>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
    </DataTemplate>
</Window.Resources>

...

    <Label Grid.Row="0" Grid.Column="0" Content="Production Scheduler" Width="Auto" Height="Auto" FontSize="40" FontWeight="Bold" HorizontalAlignment="Center" />
    <ScrollViewer Grid.Row="1" Grid.Column="0" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto">
        <ItemsControl x:Name="sched" ItemTemplate="{DynamicResource wrkCenterPanel}" />
    </ScrollViewer>

In the code I just had a List(Of List(Of String)) And I added each row as a new list of strings and then binded it to sched. Is this even the right direction to be moving in? Any help at all would be greatly appreciated.

You do seem to be heading in the right direction, however I would suggest reading up on MVVM before you continue so that you can truly understand how DataBinding and the WPF template system will be of benefit. The Prism documentation on MVVM is a good place to start, but there are countless other places to learn about MVVM with a simple search.

The jist of it is that your DataTemplates are a good start, however you can go further. Rather than just using Strings and lists of strings, you can use CLR Objects (ViewModels, in MVVM terminology) and then define DataTemplates (Views) for visually representing those CLR Objects.

The result is that your XAML will look something like this (incomplete, but demonstrative):

<Window>
    <Window.Resources>
        <DataTemplate DataType="{x:Type vms:JobViewModel}">
            <Label Content="{Binding Name}" Height ="100" Width="100" BorderThickness="1" BorderBrush="Black"/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type WorkCenterViewModel}">
            <ItemsControl ItemsSource="{Binding Jobs}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Vertical" Width="Auto" Height="Auto" />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>
        </DataTemplate>
    </Window.Resources>

    <ContentPresenter Content="{Binding WorkCenter}"/>

</Window>

And your CLR Objects will look something like this:

public class JobViewModel : ViewModel
{
    private string _name;

    public string Name
    {
       get { return _name; }
       set
       {
           _name = value;
           RaisePropertyChanged("Name");
       }
    }
}

public class WorkCenterViewModel : ViewModel
{
    private ObservableCollection<JobViewModel> _jobs;

    public ObservableCollection<JobViewModel> Jobs
    {
       get { return _jobs; }
    }
}

When you define your DataTemplates without the x:Key property, but with a DataType property instead, it will automatically apply to any instances of that type it finds.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM