2015-07-29 11 views
5

Tak więc, niewiele wiem o dekoratorach/adoratorach, ale otrzymałem wspaniałą odpowiedź here, która je wykorzystuje.Dlaczego mój niestandardowy dekorator/adorner nie działa, gdy bool zmienia się na prawdziwy?

Próbowałem je wdrożyć, ale one nie działają tak jak dla osoby, która udzieliła odpowiedzi. Starałem się, aby wszystko było tak identyczne, jak tylko potrafię.

Tu jest mój XAML:

<models:TipFocusDecorator x:Name="LoginDecorator" 
     TipText="Enter your username and password and click 'Login'" 
     IsOpen="{Binding ShowLoginTip}" 
     Grid.Column="1" Grid.Row="1"> 
    <Image Grid.Column="1" Grid.Row="1" Source="{Binding EnemyImagePath, FallbackValue={StaticResource DefaultImage}}" MaxWidth="500" MaxHeight="500"> 
     <i:Interaction.Triggers> 
      <i:EventTrigger EventName="MouseUp"> 
       <i:InvokeCommandAction Command="{Binding EnemyAttack}" /> 
      </i:EventTrigger> 
     </i:Interaction.Triggers> 
    </Image> 
</models:TipFocusDecorator> 

public class TipFocusDecorator : Decorator 
{ 

    public bool IsOpen 
    { 
     get { return (bool)GetValue(IsOpenProperty); } 
     set { SetValue(IsOpenProperty, value); } 
    } 
    // Using a DependencyProperty as the backing store for Open. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty IsOpenProperty = 
     DependencyProperty.Register("IsOpen", typeof(bool), typeof(TipFocusDecorator), 
     new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, IsOpenPropertyChanged)); 


    public string TipText 
    { 
     get { return (string)GetValue(TipTextProperty); } 
     set { SetValue(TipTextProperty, value); } 
    } 
    // Using a DependencyProperty as the backing store for TipText. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty TipTextProperty = 
     DependencyProperty.Register("TipText", typeof(string), typeof(TipFocusDecorator), new UIPropertyMetadata(string.Empty)); 


    public bool HasBeenShown 
    { 
     get { return (bool)GetValue(HasBeenShownProperty); } 
     set { SetValue(HasBeenShownProperty, value); } 
    } 

    // Using a DependencyProperty as the backing store for HasBeenShown. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty HasBeenShownProperty = 
     DependencyProperty.Register("HasBeenShown", typeof(bool), typeof(TipFocusDecorator), new UIPropertyMetadata(false)); 

    private static void IsOpenPropertyChanged(object sender, DependencyPropertyChangedEventArgs e) 
    { 
     var decorator = sender as TipFocusDecorator; 

     if ((bool)e.NewValue) 
     { 
      if (!decorator.HasBeenShown) 
       decorator.HasBeenShown = true; 

      decorator.Open(); 
     } 

     if (!(bool)e.NewValue) 
     { 
      decorator.Close(); 
     } 
    } 

    TipFocusAdorner adorner; 

    protected void Open() 
    { 
     adorner = new TipFocusAdorner(this.Child); 
     var adornerLayer = AdornerLayer.GetAdornerLayer(this.Child); 
     adornerLayer.Add(adorner); 

     MessageBox.Show(TipText); // Change for your custom tip Window 
     IsOpen = false; 
    } 

    protected void Close() 
    { 
     var adornerLayer = AdornerLayer.GetAdornerLayer(this.Child); 
     adornerLayer.Remove(adorner); 
     adorner = null; 
    } 

} 

Oto klasa Adorner:

public class TipFocusAdorner : Adorner 
{ 
    public TipFocusAdorner(UIElement adornedElement) 
     : base(adornedElement) 
    { 
    } 

    protected override void OnRender(System.Windows.Media.DrawingContext drawingContext) 
    { 
     base.OnRender(drawingContext); 

     var root = Window.GetWindow(this); 
     var adornerLayer = AdornerLayer.GetAdornerLayer(AdornedElement); 
     var presentationSource = PresentationSource.FromVisual(adornerLayer); 
     Matrix transformToDevice = presentationSource.CompositionTarget.TransformToDevice; 

     var sizeInPixels = transformToDevice.Transform((Vector)adornerLayer.RenderSize); 
     RenderTargetBitmap rtb = new RenderTargetBitmap((int)(sizeInPixels.X), (int)(sizeInPixels.Y), 96, 96, PixelFormats.Default); 

     var oldEffect = root.Effect; 
     root.Effect = new BlurEffect(); 
     rtb.Render(root); 
     root.Effect = oldEffect; 

     drawingContext.DrawImage(rtb, adornerLayer.TransformToVisual(AdornedElement).TransformBounds(new Rect(adornerLayer.RenderSize))); 
     drawingContext.DrawRectangle(new SolidColorBrush(Color.FromArgb(22, 0, 0, 0)), null, adornerLayer.TransformToVisual(AdornedElement).TransformBounds(new Rect(adornerLayer.RenderSize))); 
     drawingContext.DrawRectangle(new VisualBrush(AdornedElement) { AlignmentX = AlignmentX.Left, TileMode = TileMode.None, Stretch = Stretch.None }, 
      null, 
      AdornedElement.RenderTransform.TransformBounds(new Rect(AdornedElement.DesiredSize))); 
    } 
} 

I wreszcie, tutaj jest mój ViewModel:

private ICommand testDebug; 
public ICommand TestDebug 
{ 
    get 
    { 
     if (testDebug == null) 
     { 
      testDebug = new RelayCommand(param => this.TestDebugEx(), null); 
     } 
     return testDebug; 
    } 
} 
private void TestDebugEx() 
{ 
    ShowLoginTip = true; 
    OnPropertyChanged("ShowLoginTip"); 
} 

public bool ShowLoginTip = true; 

Po naciśnięciu przycisku, który wywołuje polecenie, polecenie działa poprawnie, a wartość ShowLoginTip zmienia się na true. Jednak nic nie działa w dekoratorze itp.

Odpowiedz

1

Dla wiązania do pracy w WPF, właściwość ShowLoginToolTip powinna być właściwością.

go zmienić na tym

private bool _showLoginToolTip; 

public bool ShowLoginToolTip 
{ 
    get 
     { 
     return _showLoginToolTip; 
     } 
    set 
     { 
     _showLoginToolTip = value; 
     OnPropertyChanged("ShowLoginTip"); 
     } 
} 

private void TestDebugEx() 
{ 
    ShowLoginTip = true; 
} 
Powiązane problemy