2014-02-23 12 views
1

Im試圖爲我的功能區提供數據模板。如何使用ItemsSource和DataTemplates呈現數據對象中的功能區

功能區聲明如下,並附帶一個ItemTemplate。

<r:Ribbon Name="RibbonMain" 
      ItemTemplate="{StaticResource HomeRibbonTabTemplate}"> 
</r:Ribbon> 

的DataTemplate中是這樣的:

<Window.Resources> 
    <DataTemplate DataType="{x:Type local:RibbonContainer}" 
        x:Key="HomeRibbonTabTemplate"> 
     <r:RibbonTab Header="{Binding Path=HeaderName}"> 
      <r:RibbonGroup Header="{Binding Path=GroupName}"> 
      </r:RibbonGroup> 
     </r:RibbonTab> 
    </DataTemplate> 
</Window.Resources> 

我然後裝上的ItemsSource:

public MainWindow() 
    { 
     InitializeComponent(); 

     var RibbonTabData = new ObservableCollection<RibbonContainer>(); 
     RibbonTabData.Add(new RibbonContainer("HeaderName", "GroupName")); 
     RibbonMain.ItemsSource = RibbonTabData; 
    } 

最後類:(這只是包含兩個字符串字段)

class RibbonContainer 
{ 
    public string HeaderName 
    { 
     get; 
     set; 
    } 

    public string GroupName 
    { 
     get; 
     set; 
    } 

    public RibbonContainer(string _headername, string _groupname) 
    { 
     HeaderName = _headername; 
     GroupName = _groupname; 
    } 
} 

我得到th在標題標題中顯示完全限定的類名稱並且無法顯示ribbongroup。 (這是數據模板應該解決的問題?) 怎麼辦?

問候

+0

嗯,據我瞭解你的問題,你設置一個容器列表是你的Ribbon控件的ItemsSource。這將自動導致Ribbon爲您創建RibbonTabs。此外,您希望以某種格式對每個RibbonTab進行模板化。但問題是您定義了另一個RibbonTab,它應放置在第一個自動創建的RibbonTab中。因此,你的應用開始動作怪異。 –

回答

5

我不太知道從哪裏開始,但也許有短警告說,在試圖創建一個RibbonControl完全從數據Binding和數據項,你真的開闢了huge ass 012 012你自己。這是因爲爲其設計代碼的開發人員使用了非常規模式,並未能充分記錄如何處理它。一些最好的來源將通過在這個網站上搜索找到。

因此,無論如何,如果你正在爲一場痛苦的艱苦奮鬥而奮鬥,請繼續閱讀。你的第一個錯誤是試圖使用DataTemplate作爲RibbonTab,因爲它延伸了System.Windows.Controls.ItemsControl,因此需要HierarchicalDataTemplate。您的第二個錯誤是在模板中聲明RibbonTab,因爲@devhedgehog在評論中提到。

你第三個錯誤是你DataTemplate設置x:Key值並將其應用到Ribbon.ItemsTemplate財產......我知道,我知道...一個明智的足夠的事情如果這不是一個RibbonControl。你必須要求那些開發者爲什麼不起作用,但你最好接受它並不適應你的代碼。您只需要刪除x:Key值和Ribbon.ItemsTemplate屬性,並讓框架隱式應用模板

現在如果您想要多個RibbonGroup,那麼您的第四個錯誤就是在RibbonTab的模板中定義該錯誤。如果您要正確執行此操作,那麼您的數據類將需要匹配Ribbon中的各種UI元素級別。通過這個,我的意思是你也需要創建一個RibbonGroupData類。該類需要一組RibbonButtonData對象,這些對象將數據提供給UI中的每個RibbonButton。所以,你應該結束了,像這樣:

public class RibbonTabData : BaseDataType 
{ 
    private string name = string.Empty; 
    private ObservableCollection<RibbonGroupData> ribbonGroupData = new ObservableCollection<RibbonGroupData>(); 

    public string Name 
    { 
     get { return name; } 
     set { name = value; NotifyPropertyChanged("Name"); } 
    } 

    public ObservableCollection<RibbonGroupData> RibbonGroupData 
    { 
     get { return ribbonGroupData; } 
     set { ribbonGroupData = value; NotifyPropertyChanged("RibbonGroupData"); } 
    } 
} 

public class RibbonGroupData : BaseDataType 
{ 
    private string name = string.Empty; 
    private ObservableCollection<RibbonButtonData> ribbonButtonData = new ObservableCollection<RibbonButtonData>(); 

    public string Name 
    { 
     get { return name; } 
     set { name = value; NotifyPropertyChanged("Name"); } 
    } 

    public ObservableCollection<RibbonButtonData> RibbonButtonData 
    { 
     get { return ribbonButtonData; } 
     set { ribbonButtonData = value; NotifyPropertyChanged("RibbonButtonData"); } 
    } 
} 

public class RibbonButtonData : BaseDataType 
{ 
    private string name = string.Empty; 

    public string Name 
    { 
     get { return name; } 
     set { name = value; NotifyPropertyChanged("Name"); } 
    } 
} 

BaseDataType類只是實現了INotifyPropertyChanged接口。當然,您需要爲ICommand和圖像來源等添加額外屬性。對於不同類型的RibbonButton s,甚至可能需要具有不同屬性的RibbonButtonData類,然後您需要一個共同的RibbonButtonBaseData類,它們全部擴展,所以你的收藏可以包含所有不同的類型。因此,有很多更適合你做,但鑑於這個例子的代碼,你可以在Ribbon這樣顯示出來:

<Ribbon:RibbonWindow.Resources> 
    <HierarchicalDataTemplate DataType="{x:Type DataTypes:RibbonTabData}" 
     ItemsSource="{Binding RibbonGroupData}"> 
     <TextBlock Text="{Binding Name}" /> 
    </HierarchicalDataTemplate> 
    <DataTemplate DataType="{x:Type DataTypes:RibbonButtonData}"> 
     <Ribbon:RibbonButton Label="{Binding Name}" 
      LargeImageSource="/WpfRibbonApplication1;component/Images/LargeIcon.png" /> 
    </DataTemplate> 
    <HierarchicalDataTemplate DataType="{x:Type DataTypes:RibbonGroupData}" 
     ItemsSource="{Binding RibbonButtonData}"> 
     <Ribbon:RibbonGroup Header="{Binding Name}" /> 
    </HierarchicalDataTemplate> 
</Ribbon:RibbonWindow.Resources> 
<Ribbon:Ribbon x:Name="Ribbon" ItemsSource="{Binding RibbonTabData}" /> 

現在被設置爲DataContextWindow視圖模型,我可以添加一些虛擬數據來測試它的所有工作:

RibbonTabData.Add(new RibbonTabData() { Name = "Tab 1", RibbonGroupData = new ObservableCollection<RibbonGroupData>() { new RibbonGroupData() { Name = "Group 1", RibbonButtonData = new ObservableCollection<RibbonButtonData>() { new RibbonButtonData() { Name = "Button 1" }, new RibbonButtonData() { Name = "Button 2" }, new RibbonButtonData() { Name = "Button 3" } } }, new RibbonGroupData() { Name = "Group 2", RibbonButtonData = new ObservableCollection<RibbonButtonData>() { new RibbonButtonData() { Name = "Button 1" }, new RibbonButtonData() { Name = "Button 2" } } } } }); 
RibbonTabData.Add(new RibbonTabData() { Name = "Tab 2" }); 
RibbonTabData.Add(new RibbonTabData() { Name = "Tab 3" }); 

而我們得到這樣的:

enter image description here

然而,即使有了這個有用的開始,你仍然有很多更多的工作要做。

+0

我最大的感謝!我已成功地設法動態添加不同的控件。 (見下面的答案) 我必須讚美你在WPF中的專業知識和技能。你是一個天賦,現在很容易添加事件和一切! – LamaCoder

1

通過閱讀Sheridans回答我成功地創建了以下結果:

enter image description here

(不同的控件與附加事件處理程序來控制通緝的可能性)。

我怎麼做了事件處理(與ribbonbutton例子)

  1. 附加標籤屬性您ribbonbutton模板(當然,數據綁定)
  2. 附加的加載事件到您的ribbonbutton模板
  3. 創建一個字典:(您windowname.xaml.cs

    public Dictionary<string, List<RoutedEventHandler>> EventLibrary = new Dictionary<string, List<RoutedEventHandler>>(); 
    
  4. 事件加入DIC tionary與事件類型

    EventLibrary.Add("NAME_RIBBONBUTTON_CLICKEVENT", new List<RoutedEventHandler> { new RoutedEventHandler(RibbonButton_Test)}); 
    
  5. 的延長線這是事件加載代碼:

    private void RibbonButton_Loaded(object sender, EventArgs e) 
        { 
        System.Windows.Controls.Ribbon.RibbonButton cmd = (System.Windows.Controls.Ribbon.RibbonButton)sender; 
    
        if (EventLibrary.ContainsKey(cmd.Tag.ToString() + "_CLICKEVENT")) 
        { 
         List<RoutedEventHandler> value = EventLibrary[cmd.Tag.ToString() + "_CLICKEVENT"]; 
         for (int i = 0; i < value.Count; i++) 
         { 
          cmd.AddHandler(RibbonButton.ClickEvent, value[i]); 
         } 
        } 
        } 
    
1

這裏是WPF的博客link to old post,那裏你可以下載archive與解決方案,在這裏你可以找到幾件有用的東西:

  • ViewModels for all Ribbon controls
  • 樣式與所有適當的綁定

因此,在使用上面的東西最終我獲得更多的簡單的解決方案:

<HierarchicalDataTemplate DataType="{x:Type ribbonVM:RibbonTabVM}" ItemsSource="{Binding Groups}"> 
    <RibbonTab DataContext="{Binding}" /> 
</HierarchicalDataTemplate> 
<HierarchicalDataTemplate DataType="{x:Type ribbonVM:RibbonGroupVM}" ItemsSource="{Binding Controls}"> 
    <RibbonGroup DataContext="{Binding}" /> 
</HierarchicalDataTemplate> 
<DataTemplate DataType="{x:Type ribbonVM:RibbonButtonVM}"> 
    <RibbonButton DataContext="{Binding}" /> 
</DataTemplate> 

我加入到虛擬機的唯一的事情是子元素的集合。

相關問題