Wenn Sie dies häufig in Ihren Ansichten tun, sollten Sie die Markuperweiterung verwenden. Höchstwahrscheinlich benötigen Sie keine Informationen aus dem Ansichts- oder Ansichtsmodell, um zu überprüfen, ob der Benutzer den richtigen Anspruch hat. In der Regel werden solche Informationen beim Anmelden abgerufen und sind nicht von der konkreten Ansicht abhängig.
public class HasClaimExtension : MarkupExtension {
private readonly string _name;
public HasClaimExtension(string name) {
_name = name;
}
public override object ProvideValue(IServiceProvider serviceProvider) {
return HasClaim();
}
private bool HasClaim() {
// check if user has this claim here
if (_name.ToLowerInvariant() == "admin")
return true;
return false;
}
}
Dann einfach:
<Button IsEnabled="{local:HasClaim Admin}" Height="20" Width="100"/>
Im unwahrscheinlichen Fall, dass Sie wirklich den Zugriff auf Ihr View-Modell benötigen, können Sie das noch tun:
public class HasClaimExtension : MarkupExtension {
private readonly string _name;
public HasClaimExtension(string name) {
_name = name;
}
public override object ProvideValue(IServiceProvider serviceProvider) {
var service = (IProvideValueTarget) serviceProvider.GetService(typeof (IProvideValueTarget));
// this is Button or whatever control you set IsEnabled of
var target = service.TargetObject as FrameworkElement;
if (target != null) {
// grab it's DataContext, that is your view model
var vm = target.DataContext as MyViewModel;
if (vm != null) {
return vm.HasClaim(_name);
}
}
return false;
}
}
public class MyViewModel {
public bool HasClaim(string claim) {
return false;
}
}
UPDATE Ihre Frage in Kommentar antworten . Du kannst es so machen. Nehmen wir an ein paar einfache Loginmanager Klasse:
public class LoginManager {
public static LoginManager Instance = new LoginManager();
private LoginManager() {
}
public bool IsLoggedIn { get; private set; }
public void Login() {
// do something, then
IsLoggedIn = true;
OnLoggedIn?.Invoke();
}
public bool HasClaim(string name) {
if (!IsLoggedIn)
throw new Exception("Cannot check claim until logged in");
return true;
}
public event Action OnLoggedIn;
}
Es hat einige Hinweise darüber, ob Ansprüche sind bereits verfügbar, und auch ein Ereignis zu benachrichtigen, wenn diese Ansprüche zur Verfügung, wenn jetzt sind sie nicht. Dann überprüfen Sie zuerst in Ihrer Markup-Erweiterung, ob die Ansprüche hier sind. Wenn ja - einfach Ergebnis zurückgeben. Wenn nicht - Rückgabe false, aber Subribbe an das Ereignis, wenn diese Ansprüche verfügbar werden. Danach - Zielobjekt mit echtem Wert aktualisieren.
public class HasClaimExtension : MarkupExtension {
private readonly string _name;
public HasClaimExtension(string name) {
_name = name;
}
public override object ProvideValue(IServiceProvider serviceProvider) {
if (LoginManager.Instance.IsLoggedIn) {
return LoginManager.Instance.HasClaim(_name);
}
// if not logged in yet
var service = (IProvideValueTarget) serviceProvider.GetService(typeof (IProvideValueTarget));
var target = service.TargetObject as FrameworkElement;
// this is dependency property you want to set, IsEnabled in this case
var targetProperty = service.TargetProperty as DependencyProperty;
if (target != null && targetProperty != null) {
if (targetProperty.PropertyType != typeof (bool)) {
// not boolean property - throw
throw new Exception("HasClaim extension should be applied to Boolean properties only");
}
// here, subscribe to event after which your claims are available
LoginManager.Instance.OnLoggedIn +=() => {
// update target property
if (Application.Current.Dispatcher.CheckAccess())
target.SetValue(targetProperty, LoginManager.Instance.HasClaim(_name));
else {
Application.Current.Dispatcher.Invoke(() => {
target.SetValue(targetProperty, LoginManager.Instance.HasClaim(_name));
});
}
};
}
return false;
}
}
Wie schaffen Sie die Tasten ... wir müssen wirklich mehr Code sehen ... – Monty
Sie können nur an Eigenschaften binden, also ist die Lösung einfach: Erstellen Sie eine Eigenschaft, die 'HasClaim (" NAME ")' aufruft und an diese bindet. –
@mike z: Wie würden Sie eine Eigenschaft mit Parameter aus der Sicht aufrufen? ... :-) Ich denke das ist der Converter wie Monty beschrieben. – Fruchtzwerg