3

2 つのユーザー コントロール間で通信するための最良の方法を見つけようとしています。さまざまなコントロールを含む 2 つのユーザー コントロールを含むメインの XAML ウィンドウがあります。各ユーザー コントロールのコード ビハインドは、関連付けられているビュー モデルに DataContext を設定するだけです。ビュー モデルには、コントロールにバインドされたオブジェクトが含まれています。私がしたいのは、ユーザー コントロール 1 のリスト ボックスで選択が変更されたときにキャプチャすることです。新しく選択したアイテムは、ユーザー コントロール 2 の編集ボックスに表示されます。ビュー モデルを使用しているため、依存関係プロパティを宣言できません。これを実行するために受け入れられている方法は何ですか?コントロールの設定方法を示すために、いくつかの基本的なコードを添付しました。

メイン ウィンドウ XAML

<Window x:Class="CommsTest.View.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:CommsTest.View"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <local:UserControl1 />
    <local:UserControl2 />
</Grid>

UserControl1 XAML

<UserControl x:Class="CommsTest.View.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">
<Grid>
    <ComboBox Height="23" HorizontalAlignment="Left" Margin="50,110,0,0" Name="comboBox1" VerticalAlignment="Top" Width="199" ItemsSource="{Binding Combo1}" />
</Grid>

UserControl1ViewModel.cs

class UserControl1ViewModel
{
    private ObservableCollection<string> combo1 = new ObservableCollection<string>();

    public ObservableCollection<string> Combo1
    {
        get { return combo1; }
    }
}

UserControl2.XAML

<UserControl x:Class="CommsTest.View.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">
<Grid>
    <TextBox Height="23" HorizontalAlignment="Left" Margin="63,84,0,0" Name="textBox1" VerticalAlignment="Top" Width="170" Text="{Binding Path=Text1}" />
</Grid>

UserControl2ViewModel.cs

class UserControl2ViewModel
{
    private string text1;

    public string Text1
    {
        get { return text1; }
        set { text1 = value; }
    }
}

UserControl2.Text1 を UserControl2.Combo1 の選択された値にするにはどうすればよいですか? ありがとう

4

3 に答える 3

5

UserControls間の通信方法を尋ねていることは理解していますが、答えはビューモデル間の通信であることをお勧めします。これは、オブジェクトを使用して簡単に実現できdelegateます。一般に、2 つの子ビュー モデルに共通の親ビュー モデルが必要です。

最近、同様の質問に回答したので、回答を重複させません。代わりに、コード例で解決策を説明している StackOverflow のここにあるビューモデル間のパラメーターの受け渡しの回答をご覧ください。


更新 >>>

子ビュー モデルに共通の親が必要であると言ったとき、継承とは何の関係もありません。親が各子ビューモデルの変数インスタンスを保持していることを意味します...親は子ビューモデルをインスタンス化します。

ビュー コード ビハインドでビュー モデル インスタンスを作成する代わりに、親ビュー モデルで作成し、次のようにビュー モデルをビューに接続できます。

Resources

<DataTemplate DataType="{x:Type ViewModels:MainViewModel}">
    <Views:MainView />
</DataTemplate>
...
<DataTemplate DataType="{x:Type ViewModels:UsersViewModel}">
    <Views:UsersView />
</DataTemplate>

次に、ビュー モデルのインスタンスを表示するだけで、適切なビューが表示されます。

ParentView

<ContentControl Content="{Binding ViewModel}" />

ParentViewModel

public BaseViewModel ViewModel { get; set; } // Implement INotifyPropertyChanged

次に、新しいビューを表示する場合:

ViewModel = new UsersViewModel();

子ビューにBaseViewModeland/or がない場合は、それぞれにプロパティを追加できます。

public MainViewmodel MainViewModel { get; set; } // Implement INotifyPropertyChanged
public UsersViewmodel UsersViewModel { get; set; } // properly for these properties

いずれにせよ、ハンドラーで「それらを一緒に接続」できるようにする場合は、親ビューからこれらのビュー モデルにアクセスする必要があります。

于 2013-10-30T15:15:52.960 に答える
1

各 UserControl に対してではなく、ViewModel を 1 つだけ使用し、DataContext を MainWindow.xaml にバインドすることをお勧めします。

また、ViewModel に実装INotifyPropertyChangedして、コードまたは ViewModel から値を変更するたびに UI に通知する必要があります。

于 2013-10-30T15:12:13.373 に答える
0

ユーザー コントロールに依存関係プロパティを持たないという自己課した制限について考える必要があるかもしれません。MVVM は全体的なアーキテクチャには適していますが、計画しているすべてのクラスとコントロールに入れるとやり過ぎになる可能性があります。

ユーザー コントロールがユーザーのための単なるコントロールである場合は、そのように動作する必要があります。TextBoxViewModel または ButtonViewModel と通信する必要はありませんでした。これらは私が使用するコントロールです。おそらくあなたのものもシンプルで、独自のビューモデルは必要ありません。次に、他のすべてのコントロールと同様に、依存関係プロパティを使用して通信できます。

于 2013-10-30T15:29:16.790 に答える