簡體   English   中英

添加控件以從ViewModel查看

[英]Adding controls to view from viewmodel

我正在嘗試制作一個簡單的任務管理器,作為在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視圖上添加背后的代碼?

我立即想到的是,我需要遍歷ViewModel,但是似乎無法讓MainWindowViewModel看到View對象(我也不知道應該如此

為您創建了一個小樣本。 看看它。

<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; }

}

TaskList和TaskListViewModel類在這里絕對是多余的。

只需創建屬性

public ObservableCollection<TaskViewModel> Tasks {get;}

在MainWindowViewModel中

並將其數據綁定到MainWindow.xaml中的ListBox或ItemsControl

將項目添加到Tasks集合時,wpf會自動為您將ListBoxItem添加到ListBox或ItemsControl。 現在,要在ListBox中顯示Task控件,只需設置ItemTemplate

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM