次の方法で共有


CommandParameter に複数の要素を指定する方法について

質問

2015年2月24日火曜日 7:18

WPF でアプリケーションを作っています。

Window に TextBox1、TextBox2、Button を配置し、Button をクリックすると、Button の CommandParameter として TextBox1、TextBox2 の Text プロパティを指定したいと考えています。

TextBox1 だけなら、以下の記述でできます。

        <Button Content="Button" Height="28" HorizontalAlignment="Left" Margin="542,338,0,0"
                Name="button3" VerticalAlignment="Top" Width="153"
                Command="{Binding Source={StaticResource myCommand}}"
                CommandParameter="{Binding ElementName=textBox1, Path=Text}">
        </Button>

ただ、2 つ以上の要素を指定したい場合の記述が分かりません。ご教授いただけないでしょうか。よろしくお願いいたします。

すべての返信 (5)

2015年2月24日火曜日 7:32 ✅回答済み

こんにちは。

マルチバインディングしてコンバータの中で配列化してやれば良いのではないでしょうか。

MainWindow.xaml

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1"
    Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:MainWindowViewModel />
    </Window.DataContext>
    <Window.Resources>
        <local:MultiText x:Key="hogeConv" />
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <TextBox Grid.Row="0" Name="txt1" Text="AAA" />
        <TextBox Grid.Row="1" Name="txt2" Text="BBB" />
        <Button Grid.Row="2" Content="Button" Command="{Binding Command}">
            <Button.CommandParameter>
                <MultiBinding Converter="{StaticResource hogeConv}">
                    <MultiBinding.Bindings>
                        <Binding ElementName="txt1" Path="Text" />
                        <Binding ElementName="txt2" Path="Text" />
                    </MultiBinding.Bindings>
                </MultiBinding>
            </Button.CommandParameter>
        </Button>
    </Grid>
</Window>

MultiText.vb

Imports System.Windows.Data

Public Class MultiText
    Implements IMultiValueConverter

    Public Function Convert(values() As Object, targetType As Type, parameter As Object, culture As Globalization.CultureInfo) As Object Implements IMultiValueConverter.Convert
        Dim a As String() = New String() {values(0).ToString, values(1).ToString}
        Return a
    End Function

    Public Function ConvertBack(value As Object, targetTypes() As Type, parameter As Object, culture As Globalization.CultureInfo) As Object() Implements IMultiValueConverter.ConvertBack
        Throw New NotImplementedException()
    End Function
End Class

※エラー考慮など一切してないです。Stringであればもっと簡単にできるのかな・・・


2015年2月24日火曜日 8:01 ✅回答済み

こんにちは

MainWindowにMainWindowViewModelを作るなら、単純に最初からバインドしとけばどうでしょうか。
これなら、ViewModelのプロパティを参照するだけなので、ややこしくCommandParameterで処理しなくていい気もします。

<TextBox Grid.Row="0" Name="txt1" Text="{Binding TextA}" />
<TextBox Grid.Row="1" Name="txt2" Text="{Binding TextB}" />


2015年2月24日火曜日 8:06 ✅回答済み

CommandParameterに独自に作成したクラスを提供する方法もあります。私は汎用的なパラメータークラスを作成し、それを使用することが多いです。以下を参考にしてみて下さい。

CommandParameter に独自クラスを指定するとデータバインディングできない?
https://social.msdn.microsoft.com/Forums/ja-JP/3f039685-9f63-4111-91e5-a38ee8e35456/commandparameter-?forum=wpfja

#ただ、inoguchiさんも書かれてますが、通常はそれぞれのTextBoxのTextプロパティをバインドし、コマンドを実行する側で(コードビハインドとかViewModel)で、それを参照する方が素直ですね。

★良い回答には回答済みマークを付けよう! MVP - .NET  http://d.hatena.ne.jp/trapemiya/


2015年2月24日火曜日 8:00

Tak1wa さん、早速のご回答ありがとうございます。

ご教示いただいた内容をアプリケーションに実装し、こちらでも期待通りの結果となりました。

とても勉強になりました。ありがとうございます!


2015年2月24日火曜日 8:26

inoguchi さん、trapemiya さん、追加情報をありがとうございます。

まだ WPF の経験が浅く、試行錯誤しながら MVVM でコーディングしているところです。

inoguchi さん、trapemiya さんの回答を見て、確かに CommandParameter で処理しなくとも私のやりたいことは実現できることに気づきました。ご指摘いただき、誠にありがとうございました。