2017-06-29 59 views
0

概述綁定在似乎沒有一個自定義的DataTemplate(擴展)內工作

我試圖創建一個自定義擴展它包含一個可視化樹,用戶可以選擇或取消選擇的節點。但是樹現在不重要。重要的是我必須覆蓋的標題,以便我可以顯示用戶需要的所有信息。

Custom control

問題

不知何故,綁定的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鏈接到Control類或什麼?

(感謝MM8)

對於在DataTemplate中每結合參考上級用戶控件

<Textbox 
... 
Text={Binding Path=XY, RelativeSource={RelativeSource AncestorType=UserControl}, FallbackValue=...}" 
... /> 

回答

2

嘗試綁定到使用父UserControlHeader屬性{RelativeSource}

<TextBlock Grid.Column="1" 
      Margin="2" 
      Text="{Binding Path=Header, RelativeSource={RelativeSource AncestorType=UserControl}, FallbackValue=Header}" 
      Foreground="Black" 
      FontWeight="Bold" 
      FontSize="14" 
      /> 
+0

你先生,是我的英雄 –