2010-03-19 98 views
1

我一直在爲此苦苦掙扎了一段時間,在WindowForms中做起來很簡單。WPF TabItem Custom ContentTemplate

我正在製作一個IRC客戶端,每個通道連接到一個標籤頁。 每個標籤需要顯示一些東西,UserList,MessageHistory,Topic。

在WindowForms中,我只是繼承自TabItem,添加了一些自定義屬性和控件,並完成了。

在WPF中,我遇到了一些小問題,以解決如何做到這一點。

我已經嘗試了很多方法,下面是我目前的方法,但我無法獲得TextBox綁定到主題屬性。

<Style TargetType="{x:Type t:IRCTabItem}" BasedOn="{StaticResource {x:Type TabItem}}" > 
    <Setter Property="ContentTemplate"> 
     <Setter.Value> 
      <DataTemplate> 
       <Grid> 
        <Grid.ColumnDefinitions> 
         <ColumnDefinition Width="540" /> 
         <ColumnDefinition /> 
        </Grid.ColumnDefinitions> 
        <StackPanel Grid.Column="0"> 
         <TextBox Text="{Binding Topic, RelativeSource={RelativeSource AncestorType={x:Type t:IRCTabItem}}}" /> 
        </StackPanel> 
       </Grid> 
      </DataTemplate>    
     </Setter.Value> 
    </Setter> 
</Style> 

而且代碼隱藏

public class IRCTabItem : TabItem 
    { 
     static IRCTabItem() 
     { 
      //This OverrideMetadata call tells the system that this element wants to provide a style that is different than its base class. 
      //This style is defined in themes\generic.xaml 
      //DefaultStyleKeyProperty.OverrideMetadata(typeof(IRCTabItem), 
      // new FrameworkPropertyMetadata(typeof(IRCTabItem))); 
     } 

     public static readonly RoutedEvent CloseTabEvent = 
      EventManager.RegisterRoutedEvent("CloseTab", RoutingStrategy.Bubble, 
       typeof(RoutedEventHandler), typeof(IRCTabItem)); 

     public event RoutedEventHandler CloseTab 
     { 
      add { AddHandler(CloseTabEvent, value); } 
      remove { RemoveHandler(CloseTabEvent, value); } 
     } 

     public override void OnApplyTemplate() 
     { 
      base.OnApplyTemplate(); 

      Button closeButton = base.GetTemplateChild("PART_Close") as Button; 
      if (closeButton != null) 
       closeButton.Click += new System.Windows.RoutedEventHandler(closeButton_Click); 
     } 

     void closeButton_Click(object sender, System.Windows.RoutedEventArgs e) 
     { 
      this.RaiseEvent(new RoutedEventArgs(CloseTabEvent, this)); 
     } 

     public bool Closeable 
     { 
      get { return (bool)GetValue(CloseableProperty); } 
      set { SetValue(CloseableProperty, value); } 
     } 
     public static readonly DependencyProperty CloseableProperty = DependencyProperty.Register("Closeable", typeof(bool), typeof(IRCTabItem), new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); 


     public List<String> UserList 
     { 
      get { return (List<string>)GetValue(UserListProperty); } 
      set { SetValue(UserListProperty, value); } 
     } 
     public static readonly DependencyProperty UserListProperty = DependencyProperty.Register("UserList", typeof(List<String>), typeof(IRCTabItem), new FrameworkPropertyMetadata(new List<String>(), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); 

     public String Topic 
     { 
      get { return (string)GetValue(TopicProperty); } 
      set { SetValue(TopicProperty, value); } 
     } 
     public static readonly DependencyProperty TopicProperty = DependencyProperty.Register("Topic", typeof(String), typeof(IRCTabItem), new FrameworkPropertyMetadata("Not Connected", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); 

     public bool HasAlerts 
     { 
      get { return (bool)GetValue(HasAlertsProperty); } 
      set { SetValue(HasAlertsProperty, value); } 
     } 
     public static readonly DependencyProperty HasAlertsProperty = DependencyProperty.Register("HasAlerts", typeof(bool), typeof(IRCTabItem), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); 


    } 

所以我的問題是:

我在做正確的方式(最佳做法)? 如果是這樣我怎麼能綁定DataTemplate屬性? 如果不是這樣,那麼實現我想要達到的目標的正確方法是什麼?

編輯1:添加了彼得·斯蒂芬斯建議 編輯2:新增可視編輯總結 編輯3:標籤你有

+0

當您編輯問題時,您應該添加某種可見的評論,以便某些現有答案不再有意義。另外,當您對Peter Stephens提出的代碼進行更改時,是否修復了任何問題? – 2010-03-19 16:49:21

+0

我以爲我已經添加了一個編輯總結 - 現在就可以完成。 事情彼得斯蒂芬斯建議沒有做出任何明顯的區別 – lloydsparkes 2010-03-19 16:55:25

回答

0

的一個問題是,你的依賴屬性不正確實施。

主題應實施像這樣:

public String Topic 
{ 
    get { return (string) GetValue(TopicProperty); } 
    set { SetValue(TopicProperty, value); } 
} 
public static readonly DependencyProperty TopicProperty = 
    DependencyProperty.Register("Topic", typeof(String), 
     typeof(IRCTabItem), new FrameworkPropertyMetadata("Not Connected", 
     FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); 

您需要處理CLR屬性爲圍繞WPF依賴屬性語法糖。讓WPF屬性處理值的存儲,否則您將有效地擁有兩個具有兩個不同值的屬性。

+0

感謝您的,它很高興知道:) – lloydsparkes 2010-03-19 12:26:21

0

我相信你的綁定表達式缺少相對來源的模式。

試試這個:

<TextBox Text="{Binding Topic, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type t:IRCTabItem}}}" /> 

的模式默認爲空,所以如果你不包括設定的東西可能不會工作這麼好。

+0

感謝您的回覆。我已經添加了這個修改,並且它沒有改變:( – lloydsparkes 2010-03-19 16:26:04