1

我希望用户能够在 10 个或更多唯一的 UserControl 之间进行选择,并以任意顺序将它们显示在列表中,其中包含任意数量的任何 UserControl 的多个实例。因此,列表可能如下所示 UC1、UC1、UC3、UC3、UC 10、UC8 等。需要注意的是,前面示例中的两个 UC1 和两个 UC3 是具有不同关联值的不同实例。本质上,我正在创建一系列命令,并将其解析为真实世界的动作。

问题:我无法将 ListView 中显示的 UserControls 绑定到 ObservableCollection 中的数据。至少,我在 UserControls 中的绑定是错误的,我不知道如何让它们工作。

我正在使用 MVVMLight。我有一个 Window 控件,它只包含一个内容控件,该控件加载了一个名为 CommandView 的 UserControl,这是我的主要显示。CommandView 目前有几个按钮,其属性绑定到 CommandViewModel 中的中继命令,这些命令将唯一的类实例添加到称为 CommandsCollection 的 ObservableCollection。ListView 绑定到封装 CommandsCollection 的属性。

我在后面的代码中使用 DataTemplate 和 DataTemplateSelector 来根据集合中该位置的类类型选择正确的 UserControl(UC1、UC2 等)。我已经成功地工作了,但是我没有将显示的 UserControl 文本框绑定回 ObservableCollection,因此在 UserControl 的文本框中没有显示任何数据。我确实在 ObservableCollection 中设置了类属性的默认值,并将集合写入文本文件并查看这些值是默认值。所以 ObservableCollection 正在查看这些值。

如何在用户控件中设置绑定?这是我在 UC1 用户控制中的内容:

    <lightext:UserControl
DataContext="{Binding VelocityCommandStatic, Source={StaticResource Locator}}">

<TextBox Text="{Binding VelocityCommandProperty.VelocityKinematic, 
         UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/> 

VelocityCommandStatic – 实际上我也对此有点困惑,但这是在 viewmodellocator.cs 中创建的用户控件的对象 (?)。

最好的绑定方法是什么?xaml 绑定点可以直接回到 ObservableCollection 吗?一个问题是,每个 UserControl 都有不同的属性,我为集合中的每个用户控件放置了一个不同的类(实例)。我会知道这些属性,但需要在 xaml 中正确设置它们。也许这种方法并不理想。我可以在视图模型中将 UserControl 的属性指向 CommandViewViewModel 中 observablecolleciton 中的正确位置吗?

4

1 回答 1

2

看,你太复杂了。您所需要的只是一个 ObservableCollection,它可以保存您的所有项目和每个项目的适当 DataTemplate。不需要 DataTemplateSelectors 或任何其他类似的东西。point directly back to the ObservableCollection此外,无论这意味着什么,都没有必要:

主窗口:

<Window x:Class="WpfApplication5.Window3"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication5"
        Title="Window3" Height="300" Width="300">
    <Window.Resources>
        <DataTemplate DataType="{x:Type local:Item1}">
            <local:UserControl1/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:Item2}">
            <local:UserControl2/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:Item3}">
            <local:UserControl3/>
        </DataTemplate>
    </Window.Resources>
    <ListBox ItemsSource="{Binding}"/>
</Window>

代码背后:

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using System.ComponentModel;

namespace WpfApplication5
{
    public partial class Window3 : Window
    {
        public Window3()
        {
            InitializeComponent();

            DataContext = new ObservableCollection<ItemBase>
                {
                    new Item1() {MyText1 = "This is MyText1 inside an Item1"},
                    new Item2() {MyText2 = "This is MyText2 inside an Item2"},
                    new Item3() {MyText3 = "This is MyText3 inside an Item3", MyBool = true}
                };
        }
    }

    public class ItemBase: INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void NotifyPropertyChange(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public class Item1: ItemBase
    {
        private string _myText1;
        public string MyText1
        {
            get { return _myText1; }
            set
            {
                _myText1 = value;
                NotifyPropertyChange("MyText1");
            }
        }
    }

    public class Item2: ItemBase
    {
        private string _myText2;
        public string MyText2
        {
            get { return _myText2; }
            set
            {
                _myText2 = value;
                NotifyPropertyChange("MyText2");
            }
        }

        private ObservableCollection<string> _options;
        public ObservableCollection<string> Options
        {
            get { return _options ?? (_options = new ObservableCollection<string>()); }
        }

        public Item2()
        {
            Options.Add("Option1");
            Options.Add("Option2");
            Options.Add("Option3");
            Options.Add("Option4");
        }
    }

    public class Item3: ItemBase
    {
        private string _myText3;
        public string MyText3
        {
            get { return _myText3; }
            set
            {
                _myText3 = value;
                NotifyPropertyChange("MyText3");
            }
        }

        private bool _myBool;
        public bool MyBool
        {
            get { return _myBool; }
            set
            {
                _myBool = value;
                NotifyPropertyChange("MyBool");
            }
        }
    }
}

用户控件1:

<UserControl x:Class="WpfApplication5.UserControl1"
             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="300" d:DesignWidth="300">
    <Border BorderBrush="Black" BorderThickness="1">
        <StackPanel>
            <TextBlock Text="This is UserControl1"/>
            <TextBlock Text="{Binding MyText1}"/>
        </StackPanel>
    </Border>
</UserControl>

用户控件2:

<UserControl x:Class="WpfApplication5.UserControl2"
             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="300" d:DesignWidth="300">
    <Border BorderBrush="Black" BorderThickness="1">
        <StackPanel>
            <TextBlock Text="This is UserControl2"/>
            <TextBox Text="{Binding MyText2}"/>
            <ComboBox ItemsSource="{Binding Options}" SelectedItem="{Binding MyText2}"/>
        </StackPanel>
    </Border>
</UserControl>

用户控件3:

<UserControl x:Class="WpfApplication5.UserControl3"
             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="300" d:DesignWidth="300">
    <Border BorderBrush="Black" BorderThickness="1">
        <StackPanel>
            <TextBlock Text="This is UserControl3"/>
            <TextBlock Text="{Binding MyText3}"/>
            <CheckBox Content="This is the MyBool Property" IsChecked="{Binding MyBool}"/>
        </StackPanel>
    </Border>
</UserControl>

只需将我的代码复制并粘贴到文件 - 新建 - WPF 应用程序中,然后自己查看结果。它看起来像这样:

在此处输入图像描述

于 2013-02-17T13:28:44.527 回答