2

バインド可能な「ClearCommand」ICommand 依存関係プロパティを使用して、いくつかのカスタム コントロール (UserControl ではない) を作成しました。このプロパティは、まさにそのとおりに動作します。コントロール (テキスト ボックスなど) からすべての値をクリアします。また、これらの同じプロパティの (一部) を、以下で説明する VM にバインドします。

次のMVVMシナリオで、これらのコントロールでClearCommandをトリガーしようとして立ち往生しています。

そのようなコントロールをビューにいくつか追加しました。SaveCommand DelegateCommandビューには、ViewModel のプロパティにバインドする [保存] ボタンも含まれています。

私がする必要があるのは、保存が成功すると、VM がClearCommandビューで見つかったコントロールをトリガーすることです。ここに画像の説明を入力

アップデート

以下にコード例を追加しました。ExampleCustomControl に似たコントロールがいくつかあります。また、完全にオフになっている場合は、これの一部を再構築することにオープンです。

制御スニペットの例:

public class ExampleCustomControl : Control {

    public string SearchTextBox { get; set; }
    public IEnumerable<CustomObject> ResultList { get; set; }

    public ExampleCustomControl() {
        ClearCommand = new DelegateCommand(Clear);
    }

    /// <summary>
    /// Dependency Property for Datagrid ItemSource.
    /// </summary>
    public static DependencyProperty SelectedItemProperty = DependencyProperty.Register("SelectedItem",
        typeof(CustomObject), typeof(ExampleCustomControl), new PropertyMetadata(default(CustomObject)));

    public CustomObject SelectedItem {
        get { return (CustomObject)GetValue(SelectedCustomObjectProperty); }
        set { SetValue(SelectedCustomObjectProperty, value); }
    }

    public static DependencyProperty ClearCommandProperty = DependencyProperty.Register("ClearCommand", typeof(ICommand),
            typeof(ExampleCustomControl), new PropertyMetadata(default(ICommand)));

    /// <summary>
    /// Dependency Property for resetting the control
    /// </summary>
    [Description("The command that clears the control"), Category("Common Properties")]
    public ICommand ClearCommand {
        get { return (ICommand)GetValue(ClearCommandProperty); }
        set { SetValue(ClearCommandProperty, value); }
    }

    public void Clear(object o) {
        SearchTextBox = string.Empty;
        SelectedItem = null;
        ResultList = null;
    }
}

ビューのスニペットの例:

<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="30"/>
    </Grid.RowDefinitions>
    <control:ExampleCustomControl Grid.Row="0"
        SelectedItem="{Binding Selection, UpdateSourceTrigger=PropertyChanged}" />
    <Button Grid.Row="1" x:Name="ResetButton" Command="{Binding SaveCommand}">
        Save
    </Button>
</Grid>

ビューモデルの例:

public class TestViewModel : WorkspaceTask {
    public TestViewModel() {
        View = new TestView { Model = this };
        SaveCommand = new DelegateCommand(Save);
    }

    private CustomObject _selection;
    public CustomObject Selection {
        get { return _selection; }
        set {
            _selection = value;
            OnPropertyChanged("Selection");
        }
    }

    public DelegateCommand SaveCommand { get; private set; }
    private void Save(object o) {
        // perform save
        // clear controls
    }
}
4

3 に答える 3

2

他の人が言っているように、VM は MVVM でビューを直接認識すべきではないため、VM がカスタム コントロールで何かをトリガーしてすべてをクリアすることは実際には意味がありません。

カスタム コントロールの を、クリアするすべてのプロパティを持つオブジェクトに設定DataContextします。これらのプロパティはすべて、テキスト ボックスなどに (双方向で) バインドされます。次に、Save() メソッドで新しいオブジェクトを設定できます。 (カスタム コントロールDataContextがバインドされている) すべてのプロパティがクリアされます (INotifyPropertyChangedオブジェクトに実装していると仮定します)。

更新しました:

私のコメントによると、現在のセットアップの回避策の例を参照してください (テストされていません):

    public static DependencyProperty SelectedItemProperty = DependencyProperty.Register("SelectedItem",
        typeof(CustomObject), typeof(ExampleCustomControl), new PropertyMetadata(default(CustomObject), OnSelectedItemChanged));


    private static void OnSelectedItemChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
    {
        var cont = source as ExampleCustomControl;

            //do all the clearing of txtboxes etc here....
        cont.SearchTextBox = string.Empty;
    }

しかし、私はまだこれらすべてを VM に移動しようとします。つまり、save コマンドで行うように clear コマンドを使用し、テキスト ボックスのテキストなどを VM のプロパティにバインドします。コマンドが呼び出されると、すべてがクリアされ、VM の Save メソッドからも簡単に呼び出すことができます。しかし、明らかに、長期的に何を達成しようとしているのか、またはselectedItemとテキストボックスなどがどのように関連しているかはわかりません。したがって、(いつものように)依存します。

于 2012-05-02T13:01:51.860 に答える
1

あなたはこれを間違った方法で考えているようです。MVVMでは、ViewModelはカスタムコントロールについて何も知らないはずです(したがって、このクリア機能に問題があります)。

要件は少しあいまいですが、次のことを考慮しましたか。

1)プロパティがVMからバインドされている場合、コントロールはこれらが変更されたことを検出できませんか?

2)XAMLレイヤーからClearを呼び出す必要があり、純粋なMVVMを維持したい場合は、ExpressionBlendSDKのCallMethodActionのようなものを検討してください。

于 2012-05-02T12:39:59.940 に答える
0

私のコメントへのフォローアップとして。TextBoxコマンドがビューをターゲットにして、 esを直接クリアしていると思われます。代わりに、コマンドで ViewModel をターゲットにして、View がバインドされているプロパティをクリアします。次に、コマンドを ViewModel のプロパティにして、必要なときに呼び出すことができます。

于 2012-05-02T12:42:11.113 に答える