2016-07-28 4 views
2

私はXAMLにRibbonComboBoxを宣言しました。私は完全には理解していない理由のためにRibbonComboBoxの子要素を見つける方法

<RibbonGroup Header="Category"> 
    <RibbonComboBox Name="cboCategory" Label="Category" HorizontalContentAlignment="Left"> 
     <RibbonGallery Name="galCategory"> 
      <RibbonGalleryCategory Name="catCategory" DisplayMemberPath="Text"> 
      </RibbonGalleryCategory> 
     </RibbonGallery> 
    </RibbonComboBox> 
    <RibbonComboBox Name="cboSubcategory" Label="Subcategory:" HorizontalContentAlignment="Left"> 
     <RibbonGallery Name="galSubcategory"> 
      <RibbonGalleryCategory Name="catSubcategory" DisplayMemberPath="Text"> 
      </RibbonGalleryCategory> 
     </RibbonGallery> 
    </RibbonComboBox> 
</RibbonGroup> 

、コンボボックス内の項目を操作するために、私はRibbonComboBoxの一部のメンバーを必要とする、私はRibbonGalleryの他のメンバーを必要とし、いくつかのタスクはRibbonGalleryCategoryのメンバーが必要です。

したがって、RibbonComboBoxのインスタンスを指定すると、子を見つけるにはどうすればよいでしょうかRibbonGalleryRibbonGalleryCategoryの要素はありますか? ControlsまたはChildrenのプロパティはありません。

私は、コントロールの子要素を見つけるためのウェブ上で次のコードが見つかりました:このコードはコンパイルされている間、私は私のコンボボックスを渡すときVisualTreeHelper.GetChildrenCount()は常に0を返します。しかし、

protected T GetChildOfType<T>(DependencyObject depObj) where T : DependencyObject 
{ 
    if (depObj == null) 
     return null; 

    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) 
    { 
     var child = VisualTreeHelper.GetChild(depObj, i); 
     var result = (child as T) ?? GetChildOfType<T>(child); 
     if (result != null) 
      return result; 
    } 
    return null; 
} 

を。したがって、コントロールの子を見つけることができません。

EDIT:名前VisualTreeHelperことで

、私はこのクラスを仮定していることは視覚的な要素を見つけるためのもので、おそらくギャラリーは別の、視覚的な要素ではありません。だから私はどのように視覚的ではない子要素を横断するかを知る必要があると思いますか?

+0

MVVMアプローチまたはコードビハインドが必要ですか? – lokusking

+0

@ lokusking:今のところ、私はコードから要素を見つけようとしています。 –

答えて

2

私は2つのアプローチを行っています。 1つはネストされた要素で、もう1つは単純なComboBoxで作成されます。ボタンはComboBoxRibbonGalleryCategory

XAML

<StackPanel> 
      <Button Content="Fill me :)" Width="80" Height="20" Click="FillMe_OnClick"/> 
      <Ribbon> 
       <RibbonGroup Header="Category"> 
        <RibbonComboBox Name="cboCategory" Label="Category" HorizontalContentAlignment="Left"> 
         <ComboBoxItem>Item 1</ComboBoxItem> 
         <ComboBoxItem>Item 2</ComboBoxItem> 
         <ComboBoxItem>Item 3</ComboBoxItem> 
         <ComboBoxItem>Item 4</ComboBoxItem> 
        </RibbonComboBox> 
        <RibbonComboBox Name="cboSubcategory" Label="Subcategory:" HorizontalContentAlignment="Left"> 
         <RibbonGallery Name="galSubcategory"> 
          <RibbonGalleryCategory Name="catSubcategory" DisplayMemberPath="Text"> 
          </RibbonGalleryCategory> 
         </RibbonGallery> 
        </RibbonComboBox> 
       </RibbonGroup> 
      </Ribbon> 
      <Button Content="Read me" Width="80" Height="20" Click="ReadMeCat_OnClick"></Button> 
      <Button Content="Read me too" Width="80" Height="20" Click="ReadMeCombo_OnClick"></Button> 
</StackPanel> 

分離コード

public MainWindow() 
     { 

      InitializeComponent(); 
     } 

     private void FillMe_OnClick(object sender, RoutedEventArgs e) 
     { 
      this.catSubcategory.Items.Add(new { Text = "Hello" }); 
      this.catSubcategory.Items.Add(new { Text = "World" }); 
      this.catSubcategory.Items.Add(new { Text = "Hello" }); 
      this.catSubcategory.Items.Add(new { Text = "Moon" }); 
     } 

     private void ReadMeCat_OnClick(object sender, RoutedEventArgs e) 
     { 
      var result = catSubcategory.Items.Cast<dynamic>().Aggregate("", (current, xx) => (string) (current + (xx.Text + "\n"))); 
      MessageBox.Show(result); 
     } 

     private void ReadMeCombo_OnClick(object sender, RoutedEventArgs e) 
     { 
      var result = cboCategory.Items.Cast<ComboBoxItem>().Aggregate("", (current, xx) => current + (xx.Content.ToString() + "\n")); 
      MessageBox.Show(result); 
     } 

私はこのdoesntのは、ムーが必要だと思うNOTE

を記入し、読みch説明。それでも必要な場合は、電話してください;)

これは実行する方法ではありません。 WPFはBindingsとMVVMを使って真のパワーを発揮します。私はあなたにもそのような例を提供することができます。

EDIT

はいあなたが正しいです。 ComboBox-Itemsは表示されますが、RibbonGalleryCategory - 接続を使用しない限り選択できません。

この資料についての別の愚かなことは、そのRibbonGalleryは実際には実際のではありません。そのControlTemplateを持つItemsControlは、VisualTreeHelperが見つかりません。

私の意見では、MVVMとDataBindingを最初から使用しないと、そのコントロールを使用するとすべてが複雑になります。

DataBindingではすべてが魅力的です。残念ながら、まだRibbonGalleryRibbonGalleryCategoryを使用する必要があります。それとも、場所が単にリボンスタイルの共通のComboBox

EDIT 2 - シンプルなMVVM-アプローチ

コード

public partial class MainWindow : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged(string propertyName) 
    { 
     this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
    } 

    public MainWindow() 
    { 

     InitializeComponent(); 
     this.Ponies.Add(new Pony() { Id = 0, Color = Brushes.DeepSkyBlue, Name = "Slayer" }); 
     this.Ponies.Add(new Pony() { Id = 1, Color = Brushes.DeepPink, Name = "Murder" }); 
     this.Ponies.Add(new Pony() { Id = 2, Color = Brushes.Yellow, Name = "Brutal" }); 
     this.DataContext = this; 
    } 

    private ObservableCollection<Pony> _ponies = new ObservableCollection<Pony>(); 
    private Pony _selectedPony; 
    public ObservableCollection<Pony> Ponies => this._ponies; 


    public Pony SelectedPony { 
     get { return _selectedPony; } 
     set { 
      if (this._selectedPony == value) return; 
      _selectedPony = value; 
      this.OnPropertyChanged("SelectedPony"); 
     } 
    } 
} 

public class Pony : INotifyPropertyChanged 
{ 
    public int Id { get; set; } 
    private string _name; 

    public string Name { 
     get { return this._name; } 
     set { 
      this._name = value; 
      this.OnPropertyChanged("Name"); 
     } 
    } 

    public Brush Color { get; set; } 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged(string propertyName) 
    { 
     this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

XAML

<Window x:Class="MyNameSpace.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     x:Name="root" 
     Title="Try WPF!" 
     mc:Ignorable="d"> 

    <Grid > 
     <Grid.RowDefinitions> 
      <RowDefinition Height="Auto"></RowDefinition> 
      <RowDefinition></RowDefinition> 
     </Grid.RowDefinitions> 
     <Ribbon> 
      <RibbonGroup Header="Category"> 
       <RibbonComboBox Label="Category" HorizontalContentAlignment="Left" > 
        <RibbonGallery SelectedItem="{Binding SelectedPony}"> 
         <RibbonGalleryCategory ItemsSource="{Binding Ponies}" > 
          <RibbonGalleryCategory.ItemTemplate> 
          <DataTemplate> 
           <TextBlock Name="tb" Text="{Binding Name}" Background="{Binding Color}"/> 
          </DataTemplate> 
          </RibbonGalleryCategory.ItemTemplate> 
         </RibbonGalleryCategory> 
        </RibbonGallery> 
       </RibbonComboBox>     
      </RibbonGroup> 
     </Ribbon> 

    </Grid> 
</Window> 

として、結果として、より多くの電力、少ないコードを参照してください:)

+0

ありがとうございます。でも、私はまだ 'cboSubcategory'のインスタンスがあると' galSubcategory'を見つけるためのコードを書くことができません。私はギャラリーを直接参照することができますが、 'RibbonComboBox'への参照から見つけることができる必要があります。 –

+0

私はMVVMに入るでしょう - 私は少しそれを学び始めました。しかし、私は実際に始まったコードをまとめておく必要があります。 –

+0

ああ。その点を逃した。 Updating ... – lokusking

関連する問題