Привязка к преобразователю к элементу управления в табличке данных списка

#wpf #data-binding

#wpf #привязка к данным

Вопрос:

Я пытаюсь передать текстовый блок преобразователю через привязку

 <DataTemplate>
    <Grid>
        <DockPanel LastChildFill="False" x:Name="dpInfo">
            <Image Source = "{Binding Data.Picture}" Height="42" HorizontalAlignment="Left" Stretch="Uniform" VerticalAlignment="Center" Width="32" Margin="16,0,0,0" DockPanel.Dock="Left"/>
            <TextBlock Text= "{Binding Data.Name}" x:Name="tbUserName" VerticalAlignment="Center" Padding="10,0,0,0" TextTrimming="CharacterEllipsis" DockPanel.Dock="Left"/>
            <TextBlock Text=  "{Binding Data.ScribbleCount, StringFormat=' ({0})', Mode=TwoWay}" VerticalAlignment="Center" DockPanel.Dock="Left"/>
        </DockPanel>
        <Rectangle x:Name="rctClickableArea" MouseLeftButtonDown="User_MouseLeftButtonDown" Fill="Black" Opacity="0">
            <Rectangle.ToolTip>
                <ToolTip DataContext="{Binding Path=PlacementTarget.DataContext, RelativeSource={x:Static RelativeSource.Self}}">
                    <ToolTip.Visibility>
                        <MultiBinding Converter="{StaticResource TooltipVisibilityConverter}">
                            <MultiBinding.Bindings>
                                <Binding Path="Data.Name"/>
                                <Binding ElementName="tbUserName"/>
                            </MultiBinding.Bindings>
                        </MultiBinding>
                    </ToolTip.Visibility>

                    <TextBlock Text="{Binding Data.Name}"/>

                </ToolTip>
            </Rectangle.ToolTip>
        </Rectangle>
    </Grid>
</DataTemplate>
 

Привязка к DataContext (путь привязки =»Data.Name «) работает, но привязка (Binding ElementName=»tbUserName») не работает, где tbUserName — это текстовый блок в DockPanel DBInfo. Есть ли у вас какие-либо идеи о том, как правильно это связать?

Ответ №1:

Возможно, у вас возникли две проблемы…

Определение имен …

Привязка имени элемента имеет строгие ограничения в отношении определения имен…

По сути, когда в привязке используется имя элемента, область имен целевого объекта используется для поиска элемента с указанным именем. Если у этого элемента нет NameScope специально для него, FrameworkElement .Метод FindScope продолжается вверх по логическому дереву и возвращается к контексту наследования, если нет логического родителя. Область имен — это объект, в котором зарегистрированы все именованные объекты.

Итак, в вашем случае ссылка на элемент вне контекста всплывающей подсказки завершается неудачей. Теперь, чтобы это работало правильно, вам нужно будет преодолеть сломанную область, используя что-то вроде Tag property …

  <Rectangle Tag="{Binding ElementName tbUserName}" ...>
    <Rectangle.ToolTip>
       <ToolTip ...>
          <ToolTip.Visibility ... >
             <MultiBinding>
                 <Binding Path="Data.Name" />
                 <Binding Path="Tag"
                          RelativeSource="{RelativeSource
                             AncestorType={x:Type Rectangle}}" ...>
 

Видимость всплывающей подсказки

Вместо привязки к видимости всплывающей подсказки вы можете использовать триггер данных с множественной привязкой к самому прямоугольнику и установить нужную всплывающую подсказку на основе значения условия…

     <Window.Resources>
       <local:TooltipVisibilityConverter x:Key="TooltipVisibilityConverter"/>
       <TextBlock x:Key="MyToolTip" Text="{Binding Data.Name}"/>
     </Window.Resources>

    <!-- Rest of the code --->

    <Rectangle.Style>
        <Style TargetType="{x:Type Rectangle}">
            <Style.Triggers>
                <DataTrigger Value="True">
                    <DataTrigger.Binding>
                          <MultiBinding
                                Converter="{StaticResource
                                   TooltipVisibilityConverter}">
                                <MultiBinding.Bindings>
                                    <Binding Path="Data.Name"/>
                                    <Binding ElementName="HelloTB"/>
                                </MultiBinding.Bindings>
                            </MultiBinding> 
                        </DataTrigger.Binding>
                        <Setter Property="ToolTip"
                                Value="{StaticResource MyToolTip}"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
    </Rectangle.Style>
 

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

Комментарии:

1. @peter Спасибо. Это указало мне в правильном направлении. Похоже {RelativeSource AncestorType={x:Type Rectangle}} , что в этом контексте это не работает, потому что прямоугольник, похоже, не является родительской цепочкой всплывающей подсказки. Кажется, он хранит его в своем свойстве PlacementTarget. Итак, объединив это с вашим замечательным предложением по установке текстового блока для свойства тега установка привязки, как <Binding Path="PlacementTarget.Tag" RelativeSource ="{RelativeSource Self}"/> решаемая проблема. Я не могу использовать подход с запуском данных, потому ActualWidth TextBlack что в то время он не был установлен.