0

私は2つのユーザーコントロールを持っています。ユーザーコントロール 1: 追加、編集、削除、保存、元に戻すなどのボタンがあるメニューバー。ユーザーコントロール 2: ユーザーがテキストボックスとパスワードボックスにテキストを入力できる画面です

しかし、保存したいときは、メニューバーと詳細画面が分離されているのではなく、ボタンとすべてを持つユーザーコントロールが1つしかないときに、次のことを行うのに慣れています:

     <Button Style="{DynamicResource SaveButton}" Command="{Binding Path=SaveCommand}">
                <Button.CommandParameter>
                    <MultiBinding Converter="{StaticResource pwConverter}">
                        <Binding ElementName="txtPassword" />
                        <Binding ElementName="txtRepeatPassword" />
                    </MultiBinding>
                </Button.CommandParameter>
            </Button>

しかし、現在、要素名「txtPassword」と「txtRepeatPassword」はそのスコープに存在しません。これは、保存ボタンをクリックしたときの SaveCommand です。これらの 2 つのパラメーターを受け取るので、2 つのパスワードが同じであるかどうかを確認できます。

    private void SaveUserExecute(object passwords)
    {
        try
        {
            var passwordvalues       = (object[])passwords;
            PasswordBox passwordBox1 = (PasswordBox)passwordvalues[0];
            PasswordBox passwordBox2 = (PasswordBox)passwordvalues[1];
       ...

この問題を解決する方法についてのアイデアはありますか?

4

2 に答える 2

0

MVVM パターンを使用すると、これは簡単です。各ユーザー コントロールとメイン ウィンドウの DataContext になる ViewModel を 1 つ持つことができます。次に、これらのそれぞれのプロパティにバインドするだけです。

以下は ViewModel の例です。これには、バインドできるプロパティによって公開されるフィールドがあります。

public class ViewModel : INotifyPropertyChanged
{
    private readonly Command _command;

    public Command Command
    {
        get { return _command; }
    }

    public ViewModel()
    {
        _command = new Command(this);
    }

    private string _textBoxOnUserControlOne;
    private string _textBoxOnUserControlTwo;

    public string TextBoxOnUserControlOne
    {
        get { return _textBoxOnUserControlOne; }
        set
        {
            if (value == _textBoxOnUserControlOne) return;
            _textBoxOnUserControlOne = value;
            OnPropertyChanged("TextBoxOnUserControlOne");
        }
    }

    public string TextBoxOnUserControlTwo
    {
        get { return _textBoxOnUserControlTwo; }
        set
        {
            if (value == _textBoxOnUserControlTwo) return;
            _textBoxOnUserControlTwo = value;
            OnPropertyChanged("TextBoxOnUserControlTwo");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

これらのプロパティの両方を操作するコマンド クラスを次に示します。

public class Command : ICommand
{
    private readonly ViewModel _viewModel;

    public Command(ViewModel viewModel)
    {
        _viewModel = viewModel;
    }

    public void Execute(object parameter)
    {
        var dataOnControlOne = _viewModel.TextBoxOnUserControlOne;
        var dataOnControlTwo = _viewModel.TextBoxOnUserControlTwo;

        //Use these values
    }

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public event EventHandler CanExecuteChanged;
}

ここで、ViewModel のフィールドの 1 つにバインドされた最初のユーザー コントロール 1 を示します。DataContext に注目してください。

<UserControl ... DataContext="{StaticResource ViewModel}">
    <Grid>
        <TextBox Height="23" HorizontalAlignment="Left" Text="{Binding TextBoxOnUserControlOne}" Margin="12,12,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" />
    </Grid>
</UserControl>

そして、同じ DataContext を持つ 2 番目の UserControl があり、テキスト ボックスは別のプロパティにバインドされています。

<UserControl ... DataContext="{StaticResource ViewModel}">
    <Grid>
        <TextBox Height="23" HorizontalAlignment="Left" Text="{Binding TextBoxOnUserControlTwo}" Margin="12,12,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" />
    </Grid>
</UserControl>

これらのユーザー コントロールと、コマンド クラスにバインドされたボタンの両方を含むメイン ウィンドウを次に示します。

<Window ... DataContext="{StaticResource ViewModel}">
    <Grid>
        <my:UserControl1 HorizontalAlignment="Left" Margin="160,69,0,0" x:Name="userControl11" VerticalAlignment="Top" Height="47" Width="155" />
        <my:UserControl2 HorizontalAlignment="Left" Margin="160,132,0,0" x:Name="userControl12" VerticalAlignment="Top" Height="48" Width="158" />
        <Button Content="Button" Command="{Binding Command}" Height="23" HorizontalAlignment="Left" Margin="199,198,0,0" Name="button1" VerticalAlignment="Top" Width="75" />
    </Grid>
</Window>

最後に、App.Xaml クラスで、すべてを結合します。

<Application ...>
    <Application.Resources>
         <wpfApplication4:ViewModel x:Key="ViewModel"/>
    </Application.Resources>
</Application>

ここでは、個別のユーザー コントロールがあり、フィールドは 1 つのビュー モデルのプロパティにバインドされています。このビューモデルはそれ自体をコマンド クラスに渡します。コマンド クラスは、別のユーザー コントロールのテキスト ボックスがバインドされているプロパティにアクセスし、ボタンが押されたときにそれらを操作できます。これが役立つことを願っています!

于 2013-08-08T13:21:34.383 に答える
0

2 つのユーザー コントロールが同じ DataContext を共有しているため、PasswordBox を表す 2 つのプロパティを作成しました。そのビューを初期化するとき、次のことを行いました。

    public InputUserView()
    {
        InitializeComponent();
        this.DataContext = InputUserViewModel.Instance;
        InputUserViewModel.Instance.PasswordBox1 = txtPassword;
        InputUserViewModel.Instance.PasswordBox2 = txtRepeatPassword;
    }

これで、ビューモデルはこれら 2 つのパスワードボックスの情報を取得しました。あまり良くないと思う

于 2013-08-08T13:10:11.210 に答える