使用ViewModel将子项添加到用户控件?

时间:2017-06-28 13:09:18

标签: c# wpf xaml viewmodel

问题:我如何将新子项添加到用户控件中?我被告知viewmodel不应该知道任何有关视图的信息,而是使用绑定。现在我已经创建了一个项目控件,并将我绑定的路径设置为包含标签的属性MyLabels。它不起作用,老实说我不确定推荐的方法是什么使它工作。

我的XAML的itemscontrol(在我的用户控件中的某个地方):

<UserControl x:Class="Test.Main"
             x:Name="this"
             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" 
             mc:Ignorable="d" 
             d:DesignHeight="600" d:DesignWidth="1000">

        <ScrollViewer Height="400" Width="900">
            <StackPanel Width="900">
                <Grid x:Name="myGrid">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>

                    <Grid.RowDefinitions>
                        <RowDefinition Height="*" />
                        <RowDefinition Height="*" />
                        <RowDefinition Height="*" />
                        <RowDefinition Height="*" />
                    </Grid.RowDefinitions>

                    <ItemsControl ItemsSource="{Binding Path=MyLabels}"/>
                </Grid>

                <Image PreviewMouseDown="AddLabel""/>
            </StackPanel>
        </ScrollViewer>
    </StackPanel>
</UserControl>

这是我的观点模型:

namespace Test {
    public partial class Main {
        public ObservableCollection<string> MyLabels { get; set; } = new ObservableCollection<string>();

        public Main() {
            InitializeComponent();
            DataContext = this;
        }

        public void AddLabel(object sender, RoutedEventArgs e) {
            for (int i = 0; i < 2; i++) {
                MyLabels.Add("eee");
            }
        }
    }
}

2 个答案:

答案 0 :(得分:0)

将视图的DataContext设置为视图模型的实例:

public Main() {
    InitializeComponent();
    DataContext = this;
}

然而,视图模型应该是它自己的类:

public MainWindow() {
    InitializeComponent();
    DataContext = new ViewModel();
}

它不应该创建任何Label元素,但strings

public class ViewModel
{
    public List<string> MyLabels { get; set; } new List<string>();

    public ViewModel()
    {
        AddLabels();
    }

    public void AddLabels()
    {
        for (int i = 0; i < 5; i++)
        {
            MyLabels.Add("Sample");
        }
    }
}

Label是用户界面元素类型,它们仅属于视图。

另请注意,您只能绑定到公共属性

  

它现在有效,唯一的问题是我不确定如何在不违反MVVM模式的情况下添加实际标签。

您在Label的{​​{1}}中添加ItemTemplate元素。此模板定义源集合中项目的外观,即在这种情况下为ItemsControl

string

答案 1 :(得分:0)

使用以下MVVM模仿(轻量级味道!),您应该能够看到在视图中创建的标签。根据您的更新,仍然会生成字符串。

<强>视图模型

123.4

MainWindow.xaml.cs(您的观点背后的代码)

public class ViewModel
{
        public ObservableCollection<string> MyStrings { get; set; }
        public ICommand AddStringCommand { get; private set; }

        public ViewModel()
        {
            if (MyStrings == null) MyStrings = new ObservableCollection<string>();

            for (int i = 0; i < 5; i++)
            {
                MyStrings.Add("string " + i);
            }

            AddStringCommand = new AddLabelCommand(AddString);

        }

        public void AddString()
        {
            MyStrings.Add("string " + (MyStrings.Count));
        }

 }

public class AddLabelCommand : ICommand
{
        readonly Action _action = null;

        public AddLabelCommand(Action commandToExecute)
        {
            _action = commandToExecute; //Handle null condition
        }

        public bool CanExecute(object parameter)
        {
            return true;
        }

        public event EventHandler CanExecuteChanged;

        public void Execute(object parameter)
        {
            _action();
        }
}   

MainWindow.xaml(内部视图)

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }

希望这为您提供一个起点!!