Как мне привязать к X позиции MouseDragElementBehavior? - PullRequest
1 голос
/ 18 февраля 2020

Моя цель - отобразить позицию X моего элемента управления в TextBlock, когда я перетаскиваю его.

xmlns:mb="http://schemas.microsoft.com/xaml/behaviors"

<cc:CardControl Name="SevenOfSpades" Canvas.Left="350" Canvas.Top="124" Width="60" Height="80" Face="S7">
    <mb:Interaction.Behaviors>
        <mb:MouseDragElementBehavior ConstrainToParentBounds="True"/>
    </mb:Interaction.Behaviors>
</cc:CardControl>
<TextBlock Text="{Binding ElementName=SevenOfSpades, Path=(mb:Interaction.Behaviors)[0].X}"/>

Я борюсь с синтаксисом Binding Path. Во время выполнения я получаю исключение:

InvalidOperationException: путь свойства недопустим. «Взаимодействие» не имеет свойства publi c с именем «Поведения».

Свойство существует, поскольку перетаскивание работает при удалении TextBlock. Я пробовал различные комбинации скобок, я даже пробовал x: stati c. Любая помощь?

Редактировать

Перечитав Привязка данных присоединенного свойства WPF , это не решит мою проблему. Path= в Xaml и скобки включены. Эта ошибка не является ошибкой привязки, это ошибка времени выполнения, возникающая внутри InitializeComponent.

MouseDragElementBehavior является частью пакета Microsoft.Xaml.Behaviors.Wpf Nuget, установленного в моем проекте.

1 Ответ

1 голос
/ 19 февраля 2020

Ах, хорошо. В этом случае код для MouseDragElementBehavior , безусловно, доступен, и даже если это не так, вы можете просто открыть сборку с помощью JustDecompile или что-то еще и просмотреть его таким образом.

Если вы посмотрите документацию для MouseDragElementBehavior , вы увидите следующее:

Свойство XProperty Dependency для позиции X перетаскиваемого элемента относительно слева от элемент root.

Таким образом, в основном вы пытаетесь связать одно свойство зависимости (TextBlock.Text) с другим (MouseDragElementBehavior.X), но для того, чтобы это работало, они должны быть часть того же визуального или логического дерева (которым они не являются, MouseDragElementBehavior является поведением). Если одно из них было прикрепленным свойством , то вы могли бы связать их напрямую, но в вашем случае вы должны связать их вместе либо со свойством в DataContext, поддерживающем INP C, либо с каким-либо прокси-объект .

Однако, даже если вы сделаете это, вы столкнетесь с проблемами. Если вы нажмете кнопку «Go to Live Visual Tree» во время работы приложения и посмотрите на свойства вашего элемента управления SevenOfSpades, вы увидите следующее:

enter image description here

Пока все хорошо. Теперь немного перетащите элемент управления и повторите этот процесс. Внезапно появилось поле RenderTransform:

enter image description here

Оглядываясь назад на код для MouseDragElementBehavior, вы обнаружите, что достаточно точно, что поведение выполняет перетаскивание, изменяя преобразование рендеринга .

Таким образом, вы пытаетесь установить положение с помощью Canvas.Top/Canvas.Left, но поведение задается с помощью применения смещения преобразования визуализации. Выбери один. Я лично использую MVVM, где все реализовано в слое модели представления, поэтому легко привязать Canvas.Top/Canvas.Left к свойствам там. Если вы хотите продолжить использовать MouseDragElementBehavior, вам нужно вместо этого связать положение ваших карточек, а также текст TextBlock с преобразованием рендеринга:

<Canvas>

    <Rectangle Name="SevenOfSpades" Width="60" Height="80" Fill="Blue">
        <Rectangle.RenderTransform>
            <TranslateTransform X="350" Y="124" />
        </Rectangle.RenderTransform>
        <mb:Interaction.Behaviors>
            <mb:MouseDragElementBehavior ConstrainToParentBounds="True" />
        </mb:Interaction.Behaviors>
    </Rectangle>

    <TextBlock Text="{Binding ElementName=SevenOfSpades, Path=RenderTransform.Value.OffsetX}" />

</Canvas>
...