添加控件以从viewmodel查看

时间:2016-06-20 20:55:33

标签: c# wpf mvvm prism

我正在尝试创建一个简单的任务管理器,以便在WPF应用程序中学习棱镜和MVVM。

目前我有一个MainWindow和MainWindowViewModel,一个TaskList和TaskListViewModel,以及一个Task和TaskViewModel。

当我加载应用程序时,我有1个按钮“新任务”最终目标是单击“新任务”按钮,然后让它向“任务列表”添加新的“任务”,但是我不能似乎弄清楚如何从MainWindowViewModel添加控件。

MainWindowViewModel:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using Prism.Mvvm;
using Prism.Commands;
using WpfApplication3.Views;

namespace WpfApplication3.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        public DelegateCommand NewTask { get; set; }

        public MainWindowViewModel()
        {
            NewTask = new DelegateCommand(Execute);
        }

        private void Execute()
        {
            MessageBox.Show("Worked");

        }
    }
}

MainWindow XAML:

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication3"
        xmlns:prism="http://prismlibrary.com/"
        xmlns:local1="clr-namespace:WpfApplication3.Views" x:Class="WpfApplication3.Views.MainWindow"
        prism:ViewModelLocator.AutoWireViewModel="True"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525" Loaded="Window_loaded">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="177*"/>
            <ColumnDefinition Width="340*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <StackPanel Orientation="Horizontal" Grid.ColumnSpan="2">
            <Button Grid.Row="0" x:Name="btnNew" Content="New Task" Command="{Binding NewTask}"/>
        </StackPanel>
        <StackPanel x:Name="taskList" Height="Auto" Grid.Row="1" VerticalAlignment="Top" Width="Auto"/>
        <local1:TaskList HorizontalAlignment="Left" VerticalAlignment="Top" Height="Auto" Grid.Row="1" Width="Auto"/>
    </Grid>
</Window>

TaskList XAML:

<UserControl x:Class="WpfApplication3.Views.TaskList"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfApplication3.Views"
             mc:Ignorable="d" 
             d:DesignHeight="250" d:DesignWidth="177">
    <Grid>
        <StackPanel HorizontalAlignment="Left" Height="Auto" VerticalAlignment="Top" Width="Auto"/>
    </Grid>
</UserControl>

任务XAML:

<UserControl x:Class="WpfApplication3.Views.Task"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfApplication3.Views"
             xmlns:prism="http://prismlibrary.com/"
             prism:ViewModelLocator.AutoWireViewModel="True"
             mc:Ignorable="d" 
             d:DesignHeight="50" d:DesignWidth="177">
    <Grid>
        <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="50" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="177"/>

    </Grid>
</UserControl>

问题:

如何动态地将“任务”用户控件添加到“任务列表”用户控件并保留MVVM,而无需在MainWindow视图上添加Code Behind?

我的直接想法是我需要浏览ViewModel,但我似乎无法让MainWindowViewModel看到View对象(我也不确定它应该

2 个答案:

答案 0 :(得分:3)

为您创建一个小样本。看看吧。

<Window x:Class="ChkList_Learning.Window2"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Title="Window2" Height="300" Width="300">
<Grid>
    <StackPanel>
        <ListBox ItemsSource="{Binding TaskList}" x:Name="taskList">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding TaskId}"></TextBlock>
                        <TextBlock Text=" - "></TextBlock>
                        <TextBlock Text="{Binding TaskName}"></TextBlock>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="ID"></TextBlock>
            <TextBox Width="100" Text="{Binding ElementName=taskList,Path=SelectedItem.TaskId}"></TextBox>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Song Name"></TextBlock>
            <TextBox Width="100"  Text="{Binding ElementName=taskList,Path=SelectedItem.TaskName}"></TextBox>
        </StackPanel>
    </StackPanel>
</Grid>

public partial class Window2 : Window
{
    public Window2()
    {
        InitializeComponent();
        this.DataContext = new TaskViewModel();
    }
}


class TaskViewModel
{
    public ObservableCollection<Task> TaskList { get; set; }

    public TaskViewModel()
    {
        TaskList = new ObservableCollection<Task>();
        for (int i = 0; i < 10; i++)
        {
            Task task = new Task();
            task.TaskId = (i + 1).ToString();
            task.TaskName = "Task Name" + (i + 1).ToString();
            TaskList.Add(task);
        }
    }
}

class Task
{
    public string TaskId { get; set; }
    public string TaskName { get; set; }

}

答案 1 :(得分:1)

TaskList和TaskListViewModel类在这里绝对是多余的。

只需创建属性

public ObservableCollection<TaskViewModel> Tasks {get;}
MainWindowViewModel中的

并将其数据绑定到ListBox或MainWindow.xaml中的ItemsControl

当您向Tasks集合添加项目时,wpf会自动将ListBoxItem添加到ListBox或ItemsControl。现在,你需要在ListBox中显示你的任务控件就是设置ItemTemplate

    <ListBox ItemsSource="{Binding TaskList}" x:Name="taskList">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <local:Task />
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>