2016-06-10 5 views
2

Ich möchte einen PRISM-Delegate-Befehl mit einem bool als Parameter verwenden. Dies ist der entsprechende Code:DelegateCommand löst aus "Angegebener Cast ist nicht gültig"

public class ChartViewModel : BindableBase 
{ 
    public DelegateCommand<bool?> ChangeZoomPanCommand { get; private set; } 

    private bool isInRealtimeMode; 
    public bool IsInRealtimeMode 
    { 
     get { return isInRealtimeMode; } 
     set 
     { 
      SetProperty(ref isInRealtimeMode, value); 
      ChangeZoomPanCommand.RaiseCanExecuteChanged(); 
     } 
    } 

    private bool dragToZoom; 
    public bool DragToZoom 
    { 
     get { return dragToZoom; } 
     set { SetProperty(ref dragToZoom, value); } 
    } 


    public ChartViewModel() 
    { 
     ChangeZoomPanCommand = new DelegateCommand<bool?>(ExecuteChangeZoomPan, CanExecuteChangeZoomPan); 
     IsInRealtimeMode = true; 
     DragToZoom = true; 
    } 

    private bool CanExecuteChangeZoomPan(bool? arg) 
    { 
     return !IsInRealtimeMode; 
    } 

    private void ExecuteChangeZoomPan(bool? enableZoom) 
    { 
     if (enableZoom.HasValue) 
     { 
      DragToZoom = enableZoom.Value; 
     } 
    } 
} 

Als ich in CanExecuteChangeZoomPan einen Haltepunkt setzte es wird nie getroffen. Das Problem tritt nach ChangeZoomPanCommand.RaiseCanExecuteChanged() auf.

Dies ist der Stacktrace:

>

at Prism.Commands.DelegateCommand`1.<>c__DisplayClass1_0.<.ctor>b__1(Object o) 
    at Prism.Commands.DelegateCommandBase.CanExecute(Object parameter) 
    at Prism.Commands.DelegateCommandBase.System.Windows.Input.ICommand.CanExecute(Object parameter) 
    at MS.Internal.Commands.CommandHelpers.CanExecuteCommandSource(ICommandSource commandSource) 
    at System.Windows.Controls.Primitives.ButtonBase.UpdateCanExecute() 
    at System.Windows.Controls.Primitives.ButtonBase.HookCommand(ICommand command) 
    at System.Windows.Controls.Primitives.ButtonBase.OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e) 
    at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e) 
    at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args) 
    at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType) 
    at System.Windows.DependencyObject.InvalidateProperty(DependencyProperty dp, Boolean preserveCurrentValue) 
    at System.Windows.Data.BindingExpressionBase.Invalidate(Boolean isASubPropertyChange) 
    at System.Windows.Data.BindingExpression.TransferValue(Object newValue, Boolean isASubPropertyChange) 
    at System.Windows.Data.BindingExpression.Activate(Object item) 
    at System.Windows.Data.BindingExpression.AttachToContext(AttachAttempt attempt) 
    at System.Windows.Data.BindingExpression.MS.Internal.Data.IDataBindEngineClient.AttachToContext(Boolean lastChance) 
    at MS.Internal.Data.DataBindEngine.Task.Run(Boolean lastChance) 
    at MS.Internal.Data.DataBindEngine.Run(Object arg) 
    at MS.Internal.Data.DataBindEngine.OnLayoutUpdated(Object sender, EventArgs e) 
    at System.Windows.ContextLayoutManager.fireLayoutUpdateEvent() 
    at System.Windows.ContextLayoutManager.UpdateLayout() 
    at System.Windows.ContextLayoutManager.UpdateLayoutCallback(Object arg) 
    at System.Windows.Media.MediaContext.InvokeOnRenderCallback.DoWork() 
    at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks() 
    at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget) 
    at System.Windows.Media.MediaContext.AnimatedRenderMessageHandler(Object resizedCompositionTarget) 
    at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) 
    at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler) 

Wenn ich das Argument Typ String alles ändern zu funktionieren scheint. Ich bekomme dann natürlich eine "Falsche" Zeichenfolge als Argument, weil das mein XAML-Befehlsparameter ist. Warum funktioniert das nicht mit irgendeinem T, da es keine Begrenzung für T zu geben scheint? Ich habe auf die harte Tour schon herausgefunden, dass T ein Objekt oder NULL-Wert sein muss, aber selbst NULL-Werte scheinen nicht zu passen. Wie man mit einem bool Argument arbeitet?

Dank

Antwort

2

Die entsprechenden Befehlsparameter Eigenschaften werden in der Regel als Objekt typisiert so wörtlich jeder als String interpretiert wird. Sie müssen den korrekten Typ übergeben, wenn Prism nicht automatisch in Ihren Typ konvertieren kann, aber die Arbeit mit Generika (wie Nullable<T>) in XAML ist generell ein Schmerz, also würde ich nicht empfehlen, dies zu tun.

auf eine einfache Art in XAML konvertieren Sie normalerweise in der Lage sein sollten, wie dies eine Bindung zu verwenden: {Binding Source=(sys:Boolean)true}, wo sys zum System Namespace in mscorlib natürlich eine XMLNS Mapping ist.

+0

Ich kann damit leben, und im Moment ist das meine Problemumgehung. Aber warum erscheint das obige Problem? Der Befehl wird nicht einmal aufgerufen, nur 'RaiseCanExecuteChanged' wird aufgerufen. Sollte das nicht einfach CanExecuteChangeZoomPan aufrufen? Wäre es sinnvoll, eine generische where-Einschränkung zu verwenden? –

+0

'CanExecute' erhält auch den Befehlsparameter, so dass die Konvertierung auch dort stattfindet. Ich glaube nicht, dass Einschränkungen hier etwas ändern würden. –

0

könnten Sie erstellen nur eine DelegateCommand<object> statt eines DelegateCommand<bool?> und es dann so handhaben:

void ExecuteChangeZoomPan(object obj) 
{ 
    if (obj is bool?) 
    { 
     bool? arg = obj as bool?; 

     // The rest of the code goes here. 
    } 
} 

Auf diese Weise ExecuteChangeZoomPan kann sehr flexibel sein, und als System.DateTime Typen wie komplex akzeptieren!

Verwandte Themen