【问题标题】:Attached.Property="{Binding}" does not workAttached.Property="{Binding}" 不起作用
【发布时间】:2013-08-13 06:44:46
【问题描述】:

我创建了一个简单的附加属性,可以在屏幕上拖动项目。

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 中启用。其他人可以让它工作吗?

编辑:解决方案

问题在于,如果没有 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;
        }
    }
}

【问题讨论】:

    标签: windows-8 windows-store-apps winrt-xaml


    【解决方案1】:

    这只是猜测,因为我面前没有编译器,但我想知道绑定基础结构是否不使用您创建的公开方法 GetCanMove 等。

    尝试在 PropertyMetadata 中注册属性更改方法

    new PropertyMetadata(false, OnCanMoveChanged)
    

    并在其中包含设置和拆卸代码

    private void OnCanMoveChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-15
      • 2017-11-10
      • 1970-01-01
      • 2012-03-29
      • 2013-08-09
      • 2017-05-24
      相关资源
      最近更新 更多