0

MVVM を使用して構築された WPF アプリケーションがあります。コントロールには、タグを挿入する必要があるテキスト ボックスがあります。私が使用しているコントロールはXamTです。

したがって、ユーザーが挿入ボタンを押すと、フォーカスされたコントロールの SelectionStart 値を照会する必要があるため、適切なテキスト インデックスにタグを挿入できます。

選択開始プロパティは DP ではないため、その値をデータバインドして変更通知を受け取ることができません。

MVVMでこれをどのように行うのだろうか?

コントロールは次のように定義されます。

<x:XamTextEditor Grid.Column="1" Grid.Row="3" 
                 Grid.ColumnSpan="2"  Margin="0 5 0 5" 
                 Template="{StaticResource ResourceKey=MyTextEditorTemplate}" 
                 Name="TBody" 
                 Text="{Binding Body}" 
                 TextWrapping="Wrap" 
                 IsAlwaysInEditMode="{Binding InEditMode,Mode=OneWay}"
                 AcceptsReturn="True" AcceptsTab="True">
    <igEditors:ValueConstraint Nullable="False" MinLength="1"/>
</x:XamTextEditor>
4

1 に答える 1

1

注: この場合、これに費やす余分な時間がない限り、完全に MVVM に適していないサード パーティ製のコントロールにチョークで書き、「ルール」を少し破って、いくつかのコードを配置します。 View クラスの behind を使用して、そのテキスト エディターへの参照をビュー モデルに渡します。

しかし、「純粋なコード ビハインド MVVM」を使用したい場合は、XamTextEditor と通信する方法を知っていて、基礎となるビュー モデルからイベントを受け取る方法を知っているある種のプロキシ オブジェクトを作成する必要があります。これは、Blend/Prism がユーザー インタラクション ダイアログを実行するために使用するメカニズムに似ています。「アクション」オブジェクトは、ビュー モデル (単にインタラクション リクエスト イベントを発生させる) とページ上の他の UI 要素との間のブリッジとして機能します。

これにアプローチする最も「堅牢な」方法は、「現在の選択位置で XamTextEditor に文字列を挿入する」方法を知っているオブジェクトを作成することだと思います。

<local:XamEditorInserter 
    SourceObject="{Binding InsertTagRequest}" 
    TargetEditor="{Binding ElementName=TBody}" />

この手法はいくつかの方法で実装できます。最も簡単な方法は、カスタム「ブリッジ」オブジェクトがサブスクライブできるイベントを持つインターフェイスを定義することです。( TriggerBaseBlend SDK から actualList<Action>を公開します。これは事実上同じものですが、実装するコードが少し増えます):

public class CustomTriggerEventArgs : EventArgs
{
  public string StringData
  { 
    get;
    set;
  }
}

public interface ICustomTrigger
{
  event EventHandler<CustomTriggerEventArgs> CustomTriggerRaised;
}

public class CustomTrigger : ICustomTrigger
{
  event EventHandler<CustomTriggerEventArgs> CustomTriggerRaised;
  public void Raise(string s)
  {
    if (this.CustomTriggerRaised != null)
    {
      this.CustomTriggerRaised(this, new CustomTriggerEventArgs { StringData = s });
    }
  }
}

SourceObjectが変更されたときに、ブリッジ オブジェクトをそのイベントに接続する必要があります。

public DependencyObject SourceObject
{
  get
  {
    return this.GetValue(SourceObjectProperty) as DependencyObject;
  }
  set
  {
    if (value is ICustomTrigger)
    {
      ((ICustomTrigger)value).CustomTriggerRaised += this.TriggerRaised;
    }
    this.SetValue(SourceObjectProperty, value);
  }
}

public void TriggerRaised(object sender, CustomTriggerEventArgs e)
{
  if (this.TargetEditor != null)
  {
    var sel = this.TargetObject.SelectionStart;
    var tag = e.StringData;
    // do whatever.
  }
}

ビューモデルでは、 type のプロパティを定義してICustomTriggerに設定し、テキスト エディターに新しいタグを挿入する必要があるときにnew CustomTrigger()そのメソッドを呼び出すだけです。Raise()

于 2012-04-27T17:08:18.030 に答える