2013-08-12 4 views
2

Я создал простое прикрепленное свойство, которое позволяет перетаскивать элемент вокруг экрана.Attached.Property = "{Binding}" не работает

1/Вот как вы бы реализовать его на элемент:

<Rectangle Fill="Green" local:MyExtension.CanMove="True" /> 

2/Это работает как шарм. Таким образом:

// in resources 
<x:Boolean x:Key="MyCanMove">true</x:Boolean> 
<Rectangle Fill="Blue" local:MyExtension.CanMove="{StaticResource MyCanMove}" /> 

3/Один синтаксис не работает. Это терпит неудачу:

<Rectangle Fill="Red" local:MyExtension.CanMove="{Binding Path=CanMove}" /> 

Что изменилось? Единственное отличие заключается в том, что он привязывает значение к прикрепленному свойству, а не устанавливает его явно или через статический ресурс.

Мне ничего не хватает. Но что это?

Вот полный XAML:

<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> 

    <Grid.DataContext> 
     <local:ViewModel/> 
    </Grid.DataContext> 

    <ToggleSwitch Header="Enable Dragging" 
        HorizontalAlignment="Center" 
        IsOn="{Binding CanMove, Mode=TwoWay}"> 
     <ToggleSwitch.RenderTransform> 
      <TranslateTransform Y="-100" /> 
     </ToggleSwitch.RenderTransform> 
    </ToggleSwitch> 

    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center"> 
     <StackPanel.Resources> 
      <Style TargetType="Rectangle"> 
       <Setter Property="Height" Value="100" /> 
       <Setter Property="Width" Value="100" /> 
      </Style> 
      <x:Boolean x:Key="MyCanMove">true</x:Boolean> 
     </StackPanel.Resources> 
     <Rectangle Fill="Green" local:MyExtension.CanMove="True" /> 
     <Rectangle Fill="Blue" local:MyExtension.CanMove="{StaticResource MyCanMove}" /> 
     <Rectangle Fill="Red" local:MyExtension.CanMove="{Binding Path=CanMove}" /> 
    </StackPanel> 

</Grid> 

А вот полный код-за:

public class ViewModel : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    bool m_CanMove = true; 
    public bool CanMove 
    { 
     get { return m_CanMove; } 
     set 
     { 
      m_CanMove = value; 
      if (PropertyChanged != null) 
       PropertyChanged(this, new PropertyChangedEventArgs("CanMove")); 
     } 
    } 
} 

public class MyExtension 
{ 
    // canmove aproperty 
    public static bool GetCanMove(DependencyObject obj) 
    { 
     return (bool)obj.GetValue(CanMoveProperty); 
    } 
    public static void SetCanMove(DependencyObject obj, bool value) 
    { 
     System.Diagnostics.Debug.WriteLine("SetCanMove"); 
     obj.SetValue(CanMoveProperty, value); 

     var rectangle = obj as FrameworkElement; 
     rectangle.ManipulationMode = ManipulationModes.TranslateX | ManipulationModes.TranslateY; 
     rectangle.ManipulationDelta -= rectangle_ManipulationDelta; 
     if (value) 
      rectangle.ManipulationDelta += rectangle_ManipulationDelta; 
    } 
    public static readonly DependencyProperty CanMoveProperty = 
     DependencyProperty.RegisterAttached("CanMove", typeof(bool), typeof(MyExtension), new PropertyMetadata(false)); 

    // implementation 
    static void rectangle_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e) 
    { 
     var rectangle = sender as FrameworkElement; 
     var canMove = System.Convert.ToBoolean(rectangle.GetValue(MyExtension.CanMoveProperty)); 
     if (canMove) 
     { 
      var transform = rectangle.RenderTransform as CompositeTransform; 
      if (transform == null) 
       rectangle.RenderTransform = (transform = new CompositeTransform()); 
      transform.TranslateX += e.Delta.Translation.X; 
      transform.TranslateY += e.Delta.Translation.Y; 
     } 
    } 
} 

Я напомню вам, что это вложенное свойство хорошо в первых двух синтаксисов работ. В результате я не могу представить, что ошибка находится в прикрепленном свойстве. И я читал на нескольких форумах, где path= необходим для привязки к прикрепленному свойству, поэтому я включил его (хотя это не имело значения). Изменение режима (OneWay, TwoWay) не имеет значения. Связывание с ElementName не имело никакого значения. Мне интересно, если это просто не включено в Windows 8.0 WinRT. Может ли кто-нибудь еще заставить это работать?

EDIT: Решение

Проблема заключалась в том, что без установки обработчика в changed событий, связывание не вызывает измененное событие. Вот обновленный код MyExtension:

public class MyExtension 
{ 
    // canmove aproperty 
    public static bool GetCanMove(DependencyObject obj) { return (bool)obj.GetValue(CanMoveProperty); } 
    public static void SetCanMove(DependencyObject obj, bool value) { obj.SetValue(CanMoveProperty, value); } 
    public static readonly DependencyProperty CanMoveProperty = 
     DependencyProperty.RegisterAttached("CanMove", typeof(bool), typeof(MyExtension), new PropertyMetadata(false, OnCanMoveChanged)); 

    // respond to change 
    private static void OnCanMoveChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     var rectangle = d as FrameworkElement; 
     rectangle.ManipulationMode = ManipulationModes.TranslateX | ManipulationModes.TranslateY; 
     rectangle.ManipulationDelta -= rectangle_ManipulationDelta; 
     if ((bool)e.NewValue) 
      rectangle.ManipulationDelta += rectangle_ManipulationDelta; 
    } 

    // implementation 
    static void rectangle_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e) 
    { 
     var rectangle = sender as FrameworkElement; 
     var canMove = System.Convert.ToBoolean(rectangle.GetValue(MyExtension.CanMoveProperty)); 
     if (canMove) 
     { 
      var transform = rectangle.RenderTransform as CompositeTransform; 
      if (transform == null) 
       rectangle.RenderTransform = (transform = new CompositeTransform()); 
      transform.TranslateX += e.Delta.Translation.X; 
      transform.TranslateY += e.Delta.Translation.Y; 
     } 
    } 
} 

ответ

3

Это только предположение, как у меня нет компилятора передо мной, но мне интересно, если связыванию инфраструктура не использует открытые методы, которые вы создали GetCanMove и т.д. .

Попробуйте зарегистрировав измененный метод собственности в PropertyMetadata

new PropertyMetadata(false, OnCanMoveChanged) 

и имеют установки и код Teardown в там

private void OnCanMoveChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
+0

Спасибо. Так оно и было. –

Смежные вопросы