次のxamlコードがあります。私のような一つのオブジェクトユーザー2つのパラメータをEventToCommandに渡す方法
public class User
{
public string Login{get;set;}
public string Password(get;set;)
}
次のxamlコードがあります。私のような一つのオブジェクトユーザー2つのパラメータをEventToCommandに渡す方法
public class User
{
public string Login{get;set;}
public string Password(get;set;)
}
通常、私はちょうどあなたがする必要はありません...言うの場としてのViewModelにtbLogin.TextとtbPassword.Textを渡すことができますどのように
<StackPanel Grid.Row="1" x:Name="spLogin">
<TextBlock Text="E-mail:"></TextBlock>
<TextBox Name="tbLogin" Text="{Binding User.Email, Mode=TwoWay}"></TextBox>
<TextBlock Text="Password:"></TextBlock>
<TextBox Name="tbPassword" Text="{Binding User.Password, Mode=TwoWay}"></TextBox>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Button Name="btnLogin" Content="Login">
<Interactivity:Interaction.Triggers>
<Interactivity:EventTrigger EventName="Click"
x:Name="SelectChangeEvent">
<Command:EventToCommand
Command="{Binding Login, Mode=TwoWay}" PassEventArgsToCommand="False" CommandParameter="{Binding}" />
</Interactivity:EventTrigger>
</Interactivity:Interaction.Triggers>
</Button>
<Button Name="btnClear" Content="Clear"/>
</StackPanel>
</StackPanel>
</Grid>
、 ViewModel(バインディングから推測される)はUser
プロパティとLogin
コマンドiselfの両方を含む必要があるため、コマンドのExcecute
メソッドからUser
プロパティにアクセスすることができます。
しかし、あなたの提示したユーザークラスがINotifyPropertyChanged
を実装していないことに気付きました。したがって、バインドが正しく機能しません。それを動作させるには、2つの可能性があります。
INotifyPropertyChanged
を実装してください。 - あなたのモデルとそれがどのように生成されるかによって、これは常に可能ではありません。INotifyPropertyChanged
を実装してください。 - モデルの定義を制御できない場合(たとえば、Webサービスプロキシによって生成される場合など)、これが唯一の方法です。しかし、たとえあなたのモデルをコントロールしていても、このオプションはあなたのビューに渡されるものをより詳細に制御できるので、検討する価値があります。ので、次のサンプルは、yoou 2番目のオプションのために行く前提としています
public class MvvmViewModel1 : ViewModelBase
{
private User _user;
#region [Login]
public const string LoginPropertyName = "Login";
public string Login {
get {
return this._user.Login;
}
set {
if (this._user.Login == value) {
return;
}
var oldValue = this._user.Login;
this._user.Login = value;
RaisePropertyChanged(LoginPropertyName);
}
}
#endregion
#region [Password]
public const string PasswordPropertyName = "Password";
public string Password {
get {
return this._user.Password;
}
set {
if (this._user.Password == value) {
return;
}
var oldValue = this._user.Password;
this._user.Password = value;
RaisePropertyChanged(PasswordPropertyName);
}
}
#endregion
#region [LoginCommand]
public RelayCommand _loginCommand;
public RelayCommand LoginCommand {
get {
return _loginCommand ?? (_loginCommand = new RelayCommand(
() => {
// perform your login action here
// access Login with: this.Login
// access Password with: this.Password
},
() => {
// can execute method - sample implementation
return (!string.IsNullOrEmpty(this.Login) && !string.IsNullOrEmpty(this.Password));
}
));
}
}
#endregion
}
明らかに、このビューモデルに一致するように、あなたのXAMLを変更する必要があります:
通常<StackPanel Grid.Row="1" x:Name="spLogin">
<TextBlock Text="E-mail:"></TextBlock>
<TextBox Name="tbLogin" Text="{Binding Login, Mode=TwoWay}"></TextBox>
<TextBlock Text="Password:"></TextBlock>
<TextBox Name="tbPassword" Text="{Binding Password, Mode=TwoWay}"></TextBox>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Button Name="btnLogin" Content="Login">
<Interactivity:Interaction.Triggers>
<Interactivity:EventTrigger EventName="Click"
x:Name="SelectChangeEvent">
<Command:EventToCommand
Command="{Binding LoginCommand}" PassEventArgsToCommand="False" />
</Interactivity:EventTrigger>
</Interactivity:Interaction.Triggers>
</Button>
<Button Name="btnClear" Content="Clear"/>
</StackPanel>
</StackPanel>
あなただけ必要CommandParameter
を使用する場合は、データテンプレート(ListBox内のアイテムテンプレートなど)内にある場合および/またはコマンドとプロパティが同じVieにないwModel。あなたは、パラメータを受け入れるようにコマンドを定義する必要があり、この場合:
#region [LoginCommand]
public RelayCommand _loginCommand;
public RelayCommand LoginCommand {
get {
return _loginCommand ?? (_loginCommand = new RelayCommand(
(p) => {
// perform your login action here
},
(p) => {
// can execute method - sample implementation
return (!string.IsNullOrEmpty(this.Login) && !string.IsNullOrEmpty(this.Password));
}
));
}
}
#endregion
そして今、あなたのViewModelにデータテンプレートのデータコンテキストを渡すためにあなたのXAML内
CommandParameter="{Binding}"
を使用することができます。
もう1つの注意点:通常、双方向バインディングは必要ありません。ただし、ビューからViewModelに情報を書き戻したい場合は例外です。
サイドノートとして:XAMLでクラスを生成/変換することはできません。したがって、ViewModelにEmail/Passwordプロパティを持つUserクラスがある場合、XAMLの空白からLogin/Passwordプロパティを持つ新しいユーザークラスを作成し、それをViewModelに渡す方法はありません。バインドは強力ですが、全能ではありません... ;-)
tbLogin.TextとtbPassword.TextはUser.EmailとUser.Passwordに双方向でバインドされているため、CommandParameterをUserに簡単にバインドできます。より大きな質問は、なぜCommandParameterがすべて必要なのでしょうか?あなたのビューモデルはUserプロパティに直接アクセスできますか?
これはすばらしい答えでした。本当に有益な情報ですただし、UserResourcesにインスタンスを作成することはできません(それはお勧めできません)。 xml名前空間を定義し、 ' 'と '{StaticResource myUser}'を渡すのが好きですか? –
ありがとう、嬉しいです。あなたは静的リソースを使って何をしたいのか分かりませんが、そうすることができます。しかし、上記のコードはもっと標準的な方法です。 – AxelEckenberger
私はあなたに同意します。私は「あなたはXAMLのクラスを生成/変換できません...」と言ったことが技術的に正確であるかどうか疑問に思っていました。私はWPFが初めてです。ほとんどの場合、良いプログラミング方法になるとは限りません。私は理解が正しいことを確認したかっただけです。 –