goo blog サービス終了のお知らせ 

げんさん日記

プログラミングで気付いた事等を書きます。

ViewModelのベースを作成する。

2021年05月20日 15時42分27秒 | WPF
基本的な処理ができるViewModelのベースを作成します。
ViewModel側でViewの表示及び終了が可能になります。

BaseBindableModelを継承してBaseViewModelの殻を作成します。
BaseBindableModelは別記事『Viewとバインドするモデルのベースを作成する。』を参照
public abstract class BaseViewModel : BaseBindableModel
{
}

ShowDialogメソッドを追加します。
別記事『ViewModelからViewを表示する』を参照

画面終了メソッドを追加します。
protected void CloseWindow()
{
  // ViewModelからViewを生成する
  public IVewResult ShowDialog(T viewModel)
  {
    // アクティブなWindowを取得します。
    var view = Application.Current.Windows.OfType<Window>().SingleOrDefault(w => w.IsActive);
    view.Close();
  }
}

使用例
public sealed class MainViewModel : BaseViewModel
{
  // サブ画面表示メソッド
  public void ShowSubWindow(string para)
  {
    // サブ画面のViewModelを作成する
    using (var vm = new SubViewModel(para))
    {
      // サブ画面ViewModelを元にViewを表示する
      var ret = base.ShowDialog(vm);
      // 自画面を終了する
      base.CloseWindow();
    }
  }
}
上記のメリットは画面表示後の処理をViewModelで連続して処理を行うことができます。

ViewModelからBehaviorのコマンドを実行する。

2020年08月31日 11時04分23秒 | WPF
ViewModelからコントロールに処理を実行したい場合があります。定義方法を下記に記します。
Behaviorにコマンドを定義します
public static readonly DependencyProperty CreateImageProperty = DependencyProperty.Register("CreateImageCommand", typeof(ICommand), typeof(InkCanvasBehavior), new PropertyMetadata(null));

XamlのコントロールにBehaiviorを定義します。その時のModeを『OneWayToSource』に設定します。
<i:Interaction.Behaviors />
    <beh:InkCanvasBehavior
        CreateImageCommand="{Binding CreateImageCommand,Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}" />

ViewModelからコマンドを実行します
this.CreateImageCommand.Execute(null);

キャンバス上の位置を取得・設定を行います。

2019年11月06日 10時41分41秒 | WPF
キャンバス上に配置されているオブジェクトの位置を取得したり設定したりする方法を下記に記します。

キャンバス上の位置を取得します。
// キャンパス上のTOP・Leftを取得します。
var top = System.Windows.Controls.Canvas.GetTop(element);
var left = System.Windows.Controls.Canvas.GetLeft(element);

// 取得した内容をポイントに変換して返します。
return new Point(left, top);

キャンバス上の左位置を変更します。
System.Windows.Controls.Canvas.SetLeft(element, positionX);

キャンバス上の上位置を変更します。
System.Windows.Controls.Canvas.SetTop(element, positionY);

指定された名前のコントロールにフォーカスを設定します。

2019年11月06日 08時41分48秒 | WPF
画面内にContentControl等が存在しても表示時のコントロールにフォーカスが当たるようにする方法を記します。
コントロールの一覧を取得する方法としてはLogicalTreeHelperとVisualTreeHelperで行う方法がありますが、LogicalTreeHelperではContentControlの内容まで検索されませんでしたのでVisualTreeHelperを使用しコントロールにフォーカスを設定します。

拡張プロパティを用意します。
public static void SetFocus(this DependencyObject parentControl, string setFocusControlName)
{
  // 子コントロールを全て取得し、コントロールの数分繰り返します。
  for (int i = 0; i
  {
    // 子コントロールを取得します。
    DependencyObject childObj = VisualTreeHelper.GetChild(parentControl, i);

    // 該当のコントロールかチェックします。
    if (childObj is FrameworkElement &&
      ((FrameworkElement)childObj).Name == setFocusControlName)
    {
      // 該当コントロールの場合はフォーカスを設定します。
      ((FrameworkElement)childObj).Focus();
      return;
    }

    // 対象コントロールに子コントロールが存在する場合は、再帰処理を行います。
    if (VisualTreeHelper.GetChildrenCount(childObj) > 0)
    {
      SetFocus(childObj, setFocusControlName);
    }
  }
}

使用例
public abstract class MainWindow : Window
{
  public void OnSetFocus(string controlName)
  {
    // コントロールにフォーカスを設定する。
    this.SetFocus(controlName);
  }
}
上記はコードビハインドでの使用例です。コントロール名はXamlのName属性です。