[英]Binding in doesn't seem to work inside a custom DataTemplate (Expander)
總覽
我正在嘗試創建一個包含視覺樹的自定義擴展器,用戶可以在其中選擇或取消選擇節點。 但是這棵樹暫時並不重要。 重要的是必須覆蓋的標頭,這樣我才能顯示用戶需要的所有信息。
問題
不知何故,DataTemplate內部文本框的綁定根本無法工作。 無論我在字段中輸入什么,始終為空,並且不會調用DependencyProperty的setter。
碼
<UserControl x:Class="WPF_Test_project.CheckableTree"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<Grid>
<Grid.Resources>
<ResourceDictionary>
<ControlTemplate x:Key="ExpanderToggleButton" TargetType="ToggleButton">
<Path Name="Chevron"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M 0 0 L 10 10 L 20 0 Z"
Fill="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Foreground}"
/>
<!-- Change appearance when is expanded -->
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter TargetName="Chevron" Property="Data" Value="M 0 10 L 10 0 L 20 10 Z" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style x:Key="MainViewExpander" TargetType="Expander">
<Setter Property="Foreground" Value="Black" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Expander">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Name="ContentRow" Height="0" />
</Grid.RowDefinitions>
<Border Name="HeaderBorder"
Grid.Row="0"
BorderThickness="0"
Background="#FFE1E1E1"
>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<ContentPresenter
Grid.Column="0"
Margin="0"
ContentSource="Header"
RecognizesAccessKey="True"
/>
<ToggleButton
Grid.Column="2"
Margin="4 4 8 4"
IsChecked="{Binding Path=IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
OverridesDefaultStyle="True"
Template="{StaticResource ExpanderToggleButton}"
Background="Black"
/>
</Grid>
</Border>
<Border Name="ContentBorder" Grid.Row="1" BorderThickness="0">
<ContentPresenter Margin="0" />
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="True">
<Setter TargetName="ContentRow" Property="Height" Value="{Binding ElementName=Content, Path=DesiredHeight}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<CheckBox Grid.Column="0"
Margin="4"
/>
<TextBlock Grid.Column="1"
Margin="2"
Text="{Binding ElementName=CT, Path=Header, FallbackValue=Header}"
Foreground="Black"
FontWeight="Bold"
FontSize="14"
/>
<TextBlock Grid.Column="2"
Margin="2"
Text="{Binding ElementName=CT, Path=NrOfFeaturesSelected, FallbackValue=5}"
Foreground="Black"
FontWeight="Bold"
FontSize="14"
HorizontalAlignment="Right"
/>
<TextBlock Grid.Column="3"
Margin="2"
Text="/"
Foreground="Black"
FontWeight="Bold"
FontSize="14"
HorizontalAlignment="Right"
/>
<TextBlock Grid.Column="4"
Margin="2"
Text="{Binding ElementName=CT, Path=NrOfFeaturesAvailable, FallbackValue=5}"
Foreground="Black"
FontWeight="Bold"
FontSize="14"
HorizontalAlignment="Right"
/>
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="TreeViewItemStyle" TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="{Binding IsExpanded}" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ResourceDictionary>
</Grid.Resources>
<Expander IsExpanded="True" Style="{StaticResource MainViewExpander}">
<TreeView ItemsSource="{Binding ElementName=CT, Path=Items}"
BorderThickness="0"
ItemContainerStyle="{StaticResource TreeViewItemStyle}"
Padding="4"
>
<TreeView.Resources>
<HierarchicalDataTemplate
x:Key="CheckableTreeItemTemplate"
ItemsSource="{Binding ElementName=CT, Path=Items}"
>
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<CheckBox Grid.Column="0"
IsChecked="{Binding IsChecked}"
VerticalAlignment="Center"
Visibility="{Binding IsCheckable, Converter={StaticResource BooleanToVisibilityConverter}}"
/>
<Label Grid.Column="1"
Content="{Binding Title}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
/>
<Label Grid.Column="3"
Content="{Binding TagCountDisplayValue}"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Visibility="{Binding ShowTagCountDisplayValue, Converter={StaticResource BooleanToVisibilityConverter}}"
/>
</Grid>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
</Expander>
</Grid>
</UserControl>
類
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
namespace WPF_Test_project
{
/// <summary>
/// Interaction logic for CheckableTree.xaml
/// </summary>
public partial class CheckableTree : UserControl
{
public CheckableTree()
{
InitializeComponent();
}
public int NrOfFeaturesSelected
{
get { return (int)GetValue(NrOfFeaturesSelectedProperty); }
set { SetValue(NrOfFeaturesSelectedProperty, value); }
}
public static readonly DependencyProperty NrOfFeaturesSelectedProperty =
DependencyProperty.Register("NrOfFeaturesSelected", typeof(Int32), typeof(CheckableTree), new UIPropertyMetadata(null));
public int NrOfFeaturesAvailable
{
get { return (int)GetValue(NrOfFeaturesSelectedProperty); }
set { SetValue(NrOfFeaturesSelectedProperty, value); }
}
public static readonly DependencyProperty NrOfFeaturesAvailableProperty =
DependencyProperty.Register("NrOfFeaturesAvailable", typeof(Int32), typeof(CheckableTree), new UIPropertyMetadata(null));
public IEnumerable<object> Items
{
get { return (IEnumerable<object>)GetValue(ItemsProperty); }
set { SetValue(NrOfFeaturesSelectedProperty, value); }
}
public static readonly DependencyProperty ItemsProperty =
DependencyProperty.Register("Items", typeof(IEnumerable<object>), typeof(CheckableTree), new UIPropertyMetadata(null));
public string Header
{
get { return (string)GetValue(HeaderProperty); }
set { SetValue(HeaderProperty, value); }
}
public static readonly DependencyProperty HeaderProperty =
DependencyProperty.Register("Header", typeof(string), typeof(CheckableTree), new UIPropertyMetadata(null));
}
}
用法
<local:CheckableTree Header="Test" NrOfFeaturesSelected="9">
</local:CheckableTree>
但是我總是得到“后備值”。 有人知道為什么會這樣嗎? 我是否必須將DataTemplate鏈接到控件類?
解決方案 (感謝mm8)
對於DataTemplate中的每個綁定,請參考父級UserControl
<Textbox
...
Text={Binding Path=XY, RelativeSource={RelativeSource AncestorType=UserControl}, FallbackValue=...}"
... />
嘗試使用{RelativeSource}
綁定到父UserControl
的Header
屬性:
<TextBlock Grid.Column="1"
Margin="2"
Text="{Binding Path=Header, RelativeSource={RelativeSource AncestorType=UserControl}, FallbackValue=Header}"
Foreground="Black"
FontWeight="Bold"
FontSize="14"
/>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.