我正在尝试创建一个简单的任务管理器,以便在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对象(我也不确定它应该)
答案 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>