Binding fails with attached property
I have created a simple attached property that enables dragging an item
around the screen.
1/ Here's how you would implement it on your element:
<Rectangle Fill="Green" local:MyExtension.CanMove="True" />
2/ This works like a charm. So does this:
// in resources
<x:Boolean x:Key="MyCanMove">true</x:Boolean>
<Rectangle Fill="Blue" local:MyExtension.CanMove="{StaticResource
MyCanMove}" />
3/ But one syntax does not work. This fails:
<Rectangle Fill="Red" local:MyExtension.CanMove="{Binding Path=CanMove}" />
What's different? The only thing different is that it is binding the value
into the attached property instead of setting it explicitly or through a
static resource.
I'm missing something. But what is it?
Here's the full 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>
And here's the full code-behind:
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;
}
}
}
I'll remind you that this attached property works fine in the first two
syntaxes. As a result, I can't imagine the error is in the attached
property. And, I read on a few forums where path= is necessary to bind to
an attached property, so I included that (though it didn't make a
difference). Changing the Mode (OneWay, TwoWay) doesn't make a difference.
Binding with an ElementName didn't make a difference. I am wondering if
this simply isn't enabled in Windows 8.0 WinRT. Can anyone else get this
to work?
No comments:
Post a Comment