WPF: Как получить значение свойства элемента управления из события, вызванного шаблоном

#wpf

#wpf

Вопрос:

Мне нужно разрешить пользователю изменять размер пользовательского элемента управления по вертикали. Итак, поиск привел меня к нескольким примерам использования класса Thumb и шаблонов. Итак, я настроил шаблоны:

 <UserControl.Resources>

    <!-- ResizeDecorator Template -->
    <ControlTemplate x:Key="ResizeDecoratorTemplate" TargetType="{x:Type Control}">
        <Grid>
            <t:ResizeThumb Height="3" Cursor="ScrollNS" VerticalAlignment="Bottom" Margin="0 0 0 -4" ItemResizeCompleted="ResizeThumb_ItemResizeCompleted" />
        </Grid>
    </ControlTemplate>

    <!-- Designer Item Template-->
    <ControlTemplate x:Key="DesignerItemTemplate" TargetType="ContentControl">
        <Grid DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}">
            <Control Template="{StaticResource ResizeDecoratorTemplate}" />
            <ContentPresenter Content="{TemplateBinding ContentControl.Content}" />
        </Grid>
    </ControlTemplate>

</UserControl.Resources>
 

Затем я настраиваю класс ResizeThumb:

 Public Class ResizeThumb
Inherits Thumb

Public Event ItemResizeCompleted(sender As Object, e As TimeSlotPanelItemResizeEventArgs)
Public Property id As Integer

Public Sub New()
    AddHandler DragDelta, AddressOf ResizeThumb_DragDelta
End Sub

Private Sub ResizeThumb_DragDelta(sender As Object, e As DragDeltaEventArgs)
    e.Handled = True
End Sub

Private Sub ItemResized(sender As Object, e As DragCompletedEventArgs) Handles Me.DragCompleted
    Dim rs As ResizeThumb = CType(sender, ResizeThumb)
    Dim gd As Grid = CType(rs.Parent, Grid)

    Dim ee As New TimeSlotPanelItemResizeEventArgs
    ee.id = id
    ee.ResizeValue = e.VerticalChange
    RaiseEvent ItemResizeCompleted(Me, ee)
End Sub
End Class
 

мои пользовательские элементы управления добавляются динамически, поэтому я добавляю шаблон во время выполнения:

     Dim si As New SchedItem(id, StartTime, Duration, SO, Title, UnitOfWork, BackgroundColor, Status, LastNote, Miles, Hours)
    Dim cc As ContentControl = New ContentControl
    cc.Content = si
    cc.Template = FindResource("DesignerItemTemplate")
 

Каждый SchedItem имеет идентификатор. Поскольку класс ResizeThumb имеет событие DragComplete, я создаю событие для передачи обратно VerticalChange, и я хочу также передать идентификатор SchedItem, размер которого был изменен. Я попытался привязать его к TemplatedParent, но это запрещено. Единственным родительским элементом ResizeThumb является сетка. Я попытался привязать тег сетки к TemplatedParent, но ничего не получил в теге.

Итак, теперь я должен спросить; Есть ли какой-либо способ получить доступ к свойству id SchedItem из обработчика событий ItemResized в классе ResizeThumb? Если да, то как? Если нет, альтернативы?

Ответ №1:

Святая корова! Я понял это. Это заняло у меня большую часть дня, но наконец-то сработало. Просто нужно было определить правильную привязку для использования. Итак, в моем коде я установил для тега ContentControl значение id.

     Dim cc As ContentControl = New ContentControl
    cc.Tag = id  '<-- right here
    cc.Content = si
    cc.Template = FindResource("DesignerItemTemplate")
 

Затем в XAML выяснили, как привязать этот тег к сетке, которая содержит свойство тега класса ResizeThumb.

     <!-- ResizeDecorator Template -->
    <ControlTemplate x:Key="ResizeDecoratorTemplate" TargetType="{x:Type Control}">
        <Grid Tag="{Binding RelativeSource={RelativeSource AncestorType=ContentControl}, Path=Tag}">
            <t:ResizeThumb Height="3" Cursor="ScrollNS" VerticalAlignment="Bottom" Margin="0 0 0 -4" ItemResizeCompleted="ResizeThumb_ItemResizeCompleted" />
        </Grid>
    </ControlTemplate>
 

И теперь в событии ItemResized я могу перейти к сетке, которая является родительской для отправителя, и присвоить тег идентификатору события.

 Private Sub ItemResized(sender As Object, e As DragCompletedEventArgs) Handles Me.DragCompleted
    Dim rs As ResizeThumb = CType(sender, ResizeThumb)
    Dim gd As Grid = CType(rs.Parent, Grid)

    Dim ee As New TimeSlotPanelItemResizeEventArgs
    ee.id = gd.Tag
    ee.ResizeValue = e.VerticalChange
    RaiseEvent ItemResizeCompleted(Me, ee)
End Sub
 

И теперь я получаю идентификатор обратно в событии.