1

ユーザーが10個以上の一意のUserControlから選択し、それらを任意の順序で任意のUserControlの複数のインスタンスとともにリストに表示できるようにしたいと思います。したがって、リストはこのUC1、UC1、UC3、UC3、UC 10、UC8などのようになります。前の例の2つのUC1と2つのUC3は、異なる値が関連付けられた異なるインスタンスであることに注意してください。基本的に、実際のアクションに解析する一連のコマンドを作成しています。

問題:ListViewに表示されているUserControlsをObservableCollectionのデータにバインドできません。少なくとも、UserControlsのバインディングが間違っているだけで、それらを機能させる方法がわかりません。

MVVMLightを使用しています。メインディスプレイであるCommandViewと呼ばれるUserControlがロードされたコンテンツコントロールのみを含むWindowコントロールがあります。CommandViewには現在、CommandsCollectionと呼ばれるObservableCollectionに一意のクラスインスタンスを追加するCommandViewModelのリレーコマンドにバインドするプロパティを持ついくつかのボタンがあります。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に直接戻ることができますか?1つの問題は、各UserControlに異なるプロパティがあり、コレクション内のユーザーコントロールごとに異なるクラス(インスタンス)を配置することです。プロパティは知っていますが、xamlで正しく設定する必要があります。たぶん、このアプローチは理想的ではありません。UserControlポイントのビューモデルのプロパティをCommandViewViewModelのobservablecollecitonの正しい位置に戻すことはできますか?

4

1 に答える 1

2

ほら、あなたはそれを過度に複雑にしている。必要なのは、すべてのアイテムとそれぞれに適切なDataTemplateを保持できるObservableCollectionです。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");
            }
        }
    }
}

UserControl1:

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

UserControl2:

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

UserControl3:

<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 に答える