Шаблон управления: как создавать привязки
Итак, у меня есть datagrid, который имеет разные цветовые ячейки в зависимости от значения ячейки.
У меня также есть всплывающая подсказка, которая отображает некоторую дополнительную информацию. Все это прекрасно работает.
Я, однако, хотел бы изменить всплывающую подсказку, чтобы показать дополнительную информацию, а также быть тем же цветом, что и ячейка. Итак, я подумал, что было бы разумно создать собственный стиль для моих подсказок. Итак, у меня есть код ниже.
<Style TargetType="ToolTip">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToolTip">
<Border CornerRadius="15,15,15,15"
BorderThickness="3,3,3,3"
Background="#AA000000"
BorderBrush="#99FFFFFF"
RenderTransformOrigin="0.5,0.5">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="2*"/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0"/>
<TextBlock Grid.Row="1"/>
<TextBlock Grid.Row="2"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
У меня есть объект, показанный ниже, который привязан к моему datagrid. Я хочу связать три свойства с тремя текстовыми полями в моей подсказке.
class MyTask
{
public string Name;
public int Code;
public string Description;
}
В моем DataGrid я делаю следующее, чтобы привязать свои данные к моему datagrid
ItemsSource="{Binding TaskList}"
Затем в DataGridTextColumn я привязываюсь к свойству, как показано ниже
DataGridTextColumn Header="Code" Binding="{Binding Code}"
Это имеет смысл для меня. Я не могу понять, как я использую привязку при создании моей настраиваемой подсказки. Я читал, что могу использовать templatebinding. Я до сих пор не понимаю, как моя подсказка привяжется к моему объекту типа MyTask в моем xaml выше?
Обновление - надеюсь, сделайте мой вопрос более ясным
Я хочу знать, как создать привязки в моем шаблоне управления (для 3 текстовых полей), а затем в основной части моего кода, как я привязываюсь к этим текстовым полям. Затем я хотел бы знать, как создать привязку для цвета фона моего шаблона управления, я считаю, что это связано с родственниками?
Когда я читаю другие примеры (изменяя свойство шаблона), я вижу строки, как показано ниже. Я действительно не понимаю, зачем вам это нужно? Это случай, если вы не правы линии ниже, вы не сможете создать привязку к свойству Padding?
<Border Padding="{Binding Padding}" ...>
Ответы
Ответ 1
Вам не нужно TemplateBindng, так как это используется для настройки полученного объекта шаблона на макет на основе динамического использования свойств реализующего элемента управления. См. эту статью CodePlex для хорошего примера, когда вам понадобится такая функциональность.
Вам просто нужно установить привязки ваших TextBlock
элементов в вашем ToolTip
. В этом случае вам действительно не нужен шаблон, за исключением того, что, поскольку вы используете ту же самую всплывающую подсказку во всех ячейках столбца, это поможет вам, поскольку вам не нужно копировать один и тот же код три раза. Вы после чего-то похожи на эту статью, всплывающая подсказка в DataGrid в WPF.
Решение, которое будет работать специально для вашего дела, будет выглядеть следующим образом:
<DataGrid Name="TestGrid1" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Name">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}">
<TextBlock.ToolTip>
<ToolTip />
</TextBlock.ToolTip>
</TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Code">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Code}">
<TextBlock.ToolTip>
<ToolTip />
</TextBlock.ToolTip>
</TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Description">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Description}">
<TextBlock.ToolTip>
<ToolTip />
</TextBlock.ToolTip>
</TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
<DataGrid.Resources>
<Style TargetType="ToolTip">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToolTip">
<Border CornerRadius="15,15,15,15"
BorderThickness="3,3,3,3"
Background="#AA000000"
BorderBrush="#99FFFFFF"
RenderTransformOrigin="0.5,0.5">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="2*"/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="{Binding Name}"/>
<TextBlock Grid.Row="1" Text="{Binding Code}"/>
<TextBlock Grid.Row="2" Text="{Binding Description}"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGrid.Resources>
</DataGrid>
Вы устанавливаете свойство ToolTip
в пределах CellTemplate
, чтобы получившийся ToolTip
, который всплывает, имеет те же DataContext
, что и активная строка в DataGrid
. Таким образом, вы можете просто выполнять привязки свойств как обычно в своем ToolTip
ContentTemplate
, так как он имеет доступ ко всем тем же свойствам, что и ваш DataGrid
для строки.
Ответ 2
Чтобы использовать базовый DataGridCell
Фон как ToolTip
Фон, привяжите ваш Border
Фон как Background="{Binding PlacementTarget.Background, RelativeSource={RelativeSource AncestorType=ToolTip, Mode=FindAncestor}}"
.
Вы пытаетесь показать все поля в подсказке ячейки. Это не имеет смысла. Но все же вы можете легко это сделать, используя
-
PlacementTarget
свойство, которое дает вам базовый элемент Visual. ContextMenu, Popup также раскрывают это свойство.
-
PlacementTarget.DataContext
предоставит вам основной объект MyTask.
-
PlacementTarget.Content
предоставит вам содержимое соответствующего DataGridCell, в вашем случае это будет TextBlock.
Итак, если вы хотите показать 3 поля в подсказке соты, ниже код будет работать для вас, используя точку с номером 2 выше.
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="Background" Value="Tomato"/>
<Setter Property="ToolTip">
<Setter.Value>
<ToolTip>
<ToolTip.Style>
<Style TargetType="ToolTip">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToolTip">
<Border CornerRadius="15,15,15,15"
BorderThickness="3,3,3,3"
Background="{Binding PlacementTarget.Background, RelativeSource={RelativeSource AncestorType=ToolTip, Mode=FindAncestor}}"
BorderBrush="#99FFFFFF"
RenderTransformOrigin="0.5,0.5">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="2*"/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="{Binding PlacementTarget.DataContext.Name, RelativeSource={RelativeSource AncestorType=ToolTip, Mode=FindAncestor}}"
/>
<TextBlock Grid.Row="0" Text="{Binding PlacementTarget.DataContext.Code, RelativeSource={RelativeSource AncestorType=ToolTip, Mode=FindAncestor}}"
/>
<TextBlock Grid.Row="0" Text="{Binding PlacementTarget.DataContext.Description, RelativeSource={RelativeSource AncestorType=ToolTip, Mode=FindAncestor}}"
/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ToolTip.Style>
</ToolTip>
</Setter.Value>
</Setter>
</Style>
</DataGrid.CellStyle>
И, если вы хотите показать только соответствующее поле ячейки в подсказке соты, затем удалите оставшиеся 2 текстовых блока и используйте только один из них:
<TextBlock Text="{Binding PlacementTarget.Content.Text, RelativeSource={RelativeSource AncestorType=ToolTip, Mode=FindAncestor}}" />
Если вы хотите показать все 3 поля, примените ToolTip
к DataGridRow
с помощью DataGrid.RowStyle
. Никаких изменений в коде не потребуется.
Ответ 3
Как насчет использования свойства цвета в MyTask?
class MyTask
{
public string Name { get; set; }
public int Code { get; set; }
public string Description { get; set; }
public SolidColorBrush Color { get; set; }
}
И привязка к свойству color:
<Style TargetType="ToolTip">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="HasDropShadow" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToolTip">
<Border Name="Border" Background="{Binding Color}" BorderBrush="{StaticResource SolidBorderBrush}" BorderThickness="1" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
<StackPanel>
<TextBlock Text="{Binding Name}" />
<TextBlock Text="{Binding Code}" />
<TextBlock Text="{Binding Description}" />
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Ответ 4
Почему бы вам не пойти на DataTemplate подсказки инструмента, например, дать ему ключ и применить его в стиле подсказки сотового элемента.
<Style TargetType="ToolTip" x:Key="ToolTipStyle">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate TargetType="ToolTip">
<Border CornerRadius="15,15,15,15"
BorderThickness="3,3,3,3"
Background="#AA000000"
BorderBrush="#99FFFFFF"
RenderTransformOrigin="0.5,0.5">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="2*"/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0"/>
<TextBlock Grid.Row="1"/>
<TextBlock Grid.Row="2"/>
</Grid>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
Теперь вы можете связать свое свойство с текстовым блоком.