2017-10-11 12 views
-1

私はWCFサービスとデータを交換するWPFクライアントアプリケーション(MVVMパターン)を開発しています。私はレンダリングされた画面(TextBlock、TextBox、GridViewなど)のすべてのコントロールに対してIsVisibileIsEnabledのプロパティを処理する効果的な方法を見つけようとしています。言い換えれば、私はユーザーが認可の観点から見る/行うことを処理する必要があります。 RelayCommandの文脈上の文脈はすでにCanExecuteですが、もう1つ必要です。WPFコントロールの承認

スクリーンをレンダリングする前に、(選択されたスクリーン、現在のユーザーグループ)のコントロールの設定を取得するために、リモートサービスが呼び出されるという考えがあります。返されたデータは、これは奇妙に見えるが、別のActive Directoryのグループを持っている別のサイト上でアプリケーションを実行する、ということができ

コントロール名(文字列)/でIsEnabled(ブール値)/のisVisible(ブール値)

のコレクションですそれぞれのコントロールで異なる意味とニーズを持っています。このアーキテクチャでは、各コントロールプロパティをサーバー側で構成可能にし、グループ名やコード内のすべての静的参照を削除することができます。

私の最初のアイデアは、コードビハインドでコントロールの設定を適用することでした(最後はスクリーン構築タスクです)。私は、画面のサービスを呼び出すと、サーバーからコンポーネントの設定を取得し、各Controlの画面の設定を参照するよりも。コントロール名が要素と一致する場合は、相対的な設定を適用します。これはコードのいくつかの行で行うことができるはずですが、私はRelayCommandがその設定を後で上書きする可能性があると思います。

もう1つのアイデアは、すべてのコントロールをViewModelの相対プロパティにマップすることです。しかし、いくつかの画面では膨大な量のプロパティが付属しています。

おそらくもっと良い方法があります。コントロールの承認を処理するには、どのような方法が良いでしょうか?これは

public bool IsSaveButtonEnabled => Thread.CurrentPrincipal.IsInRole("Admin"); 

必要があります:あなたは、現在のユーザーの権限に応じてtrueまたはfalseを返すビューモデル、例えばのソースプロパティにビュー内の要素のVisibility/IsEnabled/Commandプロパティをバインドすることができ

答えて

4

MVVMパターンに従うと、ビューのコードビハインドでは処理されません。 https://blog.magnusmontin.net/2013/03/24/custom-authorization-in-wpf/

あなたはIIdentityIPrincipalのインターフェイスから派生し、あなたが参照できることをここで利用可能なアプリケーションのスレッドのデフォルトのアイデンティティをオーバーライドするクラスを実装するWPFアプリケーションでカスタム認証を実装する方法の例があります。

WCFサービスからUIコントロールのリストを返すことは、良いアプローチのようではありません。サービスはどのUI要素についても知ってはいけません。

+0

ありがとうございます@ mm8あなたの答えです。私は各コントロールのVMのプロパティを公開することを考えました。しかし、最後に専用のプロパティの膨大な量がある可能性があります。もっと簡潔な解決方法があるのか​​どうか疑問に思っていました。 WCFからのコントロールのリストを返す背後にあるアイデアは、アプリケーションが異なる独立したサイトに対して実行されなければならないためです。さらに、各サイトには独自のADグループ(そのサイトにのみ意味がある)とその制御/グループ設定があります。 WCFは、SQL構成テーブルから返された現在のユーザーグループのACLを返します。 – gipinani

+0

IsEnabledプロパティをバインドして、パネル全体、つまりコントロールのグループを無効にすることができます。 – mm8

+0

はいtrue ..しかし、私はより細かい粒度が必要です。とにかくあなたの時間のおかげで..今のところ:) – gipinani

0

最後に、画面の要素のプロパティーをVisibility/IsEnabledにバインドするために、@ mm8によって提供された回答の一部を使用しました。

ViewModelは、タイプDictionary<string, UserAccess>のプロパティを公開します。各キー・エントリは、要素アクセス構成を表します。スクリーンがロードされると、ディクショナリが塗りつぶされます。

添付プロパティを使用して、ビューでのコードの書き出しを簡略化しました。

<Button 
    x:Name="btnCustomTableEditor" 
    Command="{Binding NavCommand}" 
    CommandParameter="CustomTableEditor" 
    common:UserAccess.UserAccessType="{Binding AuthenticationSchema}"> 

、ここでのDependencyProperty

public static readonly DependencyProperty UserAccessProperty = 
     DependencyProperty.RegisterAttached(
      "UserAccessType", 
      typeof(Dictionary<string, UserConfiguration>), 
      typeof(UserAccess), 
      new PropertyMetadata(
       new PropertyChangedCallback(UserAcccessnChanged))); 

の実装とPropertyChangedCallBackに私はFrameworkElement/Dictionary<string, UserConfiguration>

private static void UserAcccessnChanged (DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    FrameworkElement frameworkElement = (FrameworkElement)d; 
    Dictionary<string, UserConfiguration> myDict = 
     (Dictionary<string, UserConfiguration>)e.NewValue; 
    UserConfiguration uc = myDict[frameworkElement.Name]; 

への参照を取得し、その後、私は可視性の上で動作することができます/要素の有効なプロパティ。各要素には、指定された名前が必要です。

私はこれがエレガントかもしれないとは確信していませんが、汚い仕事をするのに効果があるようです。

関連する問題