2017-06-29 4 views
0

私はWPFアプリケーションを作成しており、効果的なMVVMの実践を学んでいます。インターフェイス(MainWindow.xaml内)にMenuItemボタンがあり、CommandプロパティをICommandにバインドしたいと思います。アプリケーションのどこにでも設定/取得できるアプリケーションスコープ変数を作成するにはどうすればよいですか? (WPF/MVVM)

アプリケーションが起動すると、本来はfalseに設定されるように設定されているbool(アプリケーションのどこからでも設定/取得できます)が必要になります。 "File> New" MenuItemがアクティブになっているとき、私はコマンドを起動し、その "CanExecute"メソッドでアプリケーションスコープ変数をチェックして、MenuItemを有効または無効にすることにします。

私の問題は、この変数(またはプロパティ)を格納/インスタンス化するのに最適な場所が正確にわからないということです。

"Workspace"クラス(ブール変数を保持する)でシングルトンパターンのデザインを実装するなど、さまざまな組み合わせを試しています。また、静的なクラスと変数を使っています。

私のコードを以下に示します。

XAML:

<MenuItem Header="_File"> 
      <MenuItem Header="_New Project" Command="{Binding NewProjectCommand, Source={StaticResource project}}"/> 
      <MenuItem Header="_Open Project"/> 
</MenuItem> 

App.xaml.cs:

public WorkspaceViewModel WorkspaceInfo { get; set; } 

public partial class App : Application 
{ 
    public App() 
    { 
     //Store variable here? How? And what is the best way to expose it to my Commands? 
    } 

} 

WorkspaceViewModel.cs:

class WorkspaceViewModel : Workspace 
{ 

} 

NewProjectCommand.cs:

class NewProjectCommand : ICommand 
{ 

    public NewProjectCommand(ProjectViewModel projectViewModel) 
    { 
    } 

    public event EventHandler CanExecuteChanged; 

    public bool CanExecute(object parameter) 
    { 
     //Do an evaluation here using the new bool in App.xaml.cs 
     //return true/false, based on the evaluation 

    } 

    public void Execute(object parameter) 
    { 
     //Perform steps here to switch the bool in App.xaml.cs, and perform other command functionality 
    } 
} 

Workspace.cs:

class Workspace : INotifyPropertyChanged 
{ 
    private bool _isProjectOpen; 

    public bool IsProjectOpen 
    { 
     get { return _isProjectOpen; } 
     set 
     { 
      _isProjectOpen = value; 
      OnPropertyChanged(); 
     } 
    } 


    #region INotifyPropertyChanged members 

    public event PropertyChangedEventHandler PropertyChanged; 

    private void OnPropertyChanged([CallerMemberName] string propertyName = "") 
    { 
     var handler = PropertyChanged; 

     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
    #endregion 
} 

私は基本的に自分のアプリケーションの最高レベルで真/偽の値を格納したいのです、そうすれば、私は "CanExecute"の変数を取得し、すべての私のICommandsの "Execute"メソッドで変数を設定することができるので、すべての私のMenuItemsが有効になり、適切な時間。

これはかなり長引く質問ですが、どんな助力も大変ありがとうございます。私が追加情報を投稿する必要があれば、私はそうすることができます!

ありがとうございました!

+1

によって「に設定することができます/アプリケーションのどこからでも入手」? –

+0

さまざまな答えが記述されているので、これを行う方法はたくさんあります。 MVVMのベストプラクティスを学んでいるのであれば、この変数をアプリケーションの状態を格納し、アプリケーションの状態を知る必要のあるすべてのViewModelにそのインタフェースを注入するために使用するモデル/サービスに入れることをお勧めします。このようにして、ViewModelのテスト容易性を損なうことはありません。 –

+0

私が潜在的な選択肢を検討していた頃、私は本当に簡単な解決策があることを期待していました。私はシングルトンではなく、アクセスしやすいプロパティに傾いていますが、最終的にどのように使用するかを学ぶことができるようになることを願っています。ありがとう! –

答えて

2

「アプリケーションスコープの変数」で設定 は、Appクラスのプロパティとして宣言することができます。

public partial class App : Application 
{ 
    public bool YourProperty { get; set; } // is false by default 
} 

今すぐプロパティがシングルトンと間違っていた何

((App)Application.Current).YourProperty = true; 

var propertyValue = ((App)Application.Current).YourProperty; 
+0

これは完璧です - 私が必要としていたものです。私は自分の問題は、最初にプロパティを正しく設定することができないという事実を組み合わせたものだと思います。そして、私の "CanExecuteChanged"メソッドで何も持っていないので、私のMenuItem.IsEnabledは正しく更新されていませんでした! –

3

ストア静的Application.CurrentインスタンスのProperties辞書に値:

Application.Current.Properties["NameOfProperty"] = false; 
var myProperty = (bool)Application.Current.Properties["NameOfProperty"]; 
+1

これを試した後、それもうまくいきました。私のアプリケーションのどこか他の場所で使用することができます。ありがとうございました! –

1

2つの方法
1]いずれかのプロジェクトプロパティ]をクリックして、より以上のプロジェクトに
右クリックを設定として保存し設定に行く
ここで設定を行います。
enter image description here あなたがアクセスしたり、コード

Properties.Settings.Default.SavedInputString 

2]
XMLファイルは、作成、読み取りおよび更新し、その高速な方法が容易なカスタムXMLファイルに保存してプログラム的 それらを操作することができますロードするために、実行時

+0

OPは明らかにプロパティ値を保存して再ロードすることを望まない。 – Clemens

+0

あなたの提案する両方のオプションは、アプリケーションの他のメカニズムにとって非常に便利なので、私は間違いなく設定にユーザ定義の「環境設定」を保存します。私は実際にアプリケーションを使ってユーザーが入力したデータをXMLファイルに書き込んでいるので、すぐにその部分について作業します。私は私の異なる選択肢について考えていた、それは私の次のハードルの一つになるでしょう。 –

関連する問題