2013-04-26 155 views
2

我不知道如何獲取menuItem的父項?我找遍了所有角落找尋,但不能得到一個很好的答案...WPF獲取menuItem的父項

我的XAML是:

<DockPanel> 
      <Menu DockPanel.Dock="Right" SnapsToDevicePixels="True" Margin="2,0,0,0"> 
       <MenuItem Header="Devices"> 
        <local:MenuItemWithRadioButton x:Name="MenuItemVideoDevices" Header="Video"> 
        </local:MenuItemWithRadioButton> 
        <local:MenuItemWithRadioButton x:Name="MenuItemAudioDevices" Header="Audio"> 
        </local:MenuItemWithRadioButton> 
       </MenuItem> 
      </Menu> 
</DockPanel> 

private void MenuItemWithRadioButtons_Click(object sender, System.Windows.RoutedEventArgs e) 
{ 
     MenuItem mi = sender as MenuItem; 
     if (mi != null) 
     { 
      RadioButton rb = mi.Icon as RadioButton; 
      if (rb != null) 
      { 
       rb.IsChecked = true; 
      } 
      //Here I want to get the parent menuItem 
     }    
} 

在代碼中,當我點擊像「MenuItemVideoDevices」,事件處理功能被觸發submenuItem ,但我不知道如何在這個函數中獲得menuItem「Video」。

任何人都知道嗎?

回答

0

MenuItem有一個屬性Parent

var parent = mi.Parent; 
+1

嗨,謝謝!但我發現mi.Parent爲空! 「父」是指父菜單項嗎? – user991800 2013-04-26 08:29:23

1

如果您發現該MenuItem.Parent屬性是null,那麼你的代碼是不是因爲你貼什麼那麼簡單。我下面簡單的XAML窗口放在一起,它工作得很好:

<Window x:Class="TestSO16231375MenuItemParent.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <DockPanel> 
    <Menu DockPanel.Dock="Right" SnapsToDevicePixels="True" Margin="2,0,0,0"> 
     <MenuItem Header="Devices"> 
     <MenuItem x:Name="MenuItemVideoDevices" Header="Video" Click="MenuItemVideoAudioDevices_Click"/> 
     <MenuItem x:Name="MenuItemAudioDevices" Header="Audio" Click="MenuItemVideoAudioDevices_Click"/> 
     </MenuItem> 
    </Menu> 
    </DockPanel> 
</Window> 

也就是說,Click事件處理程序可以成功地獲取正確的,預計使用Parent財產MenuItem父:

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void MenuItemVideoAudioDevices_Click(object sender, RoutedEventArgs e) 
    { 
     MenuItem menuItem = (MenuItem)sender; 

     MessageBox.Show("Parent's header text: " + ((MenuItem)menuItem.Parent).Header.ToString()); 
    } 
} 


由於您沒有提供可靠地重現您的問題的a good, minimal, complete_ code example,因此我無法確定您的測試中爲什麼Parent屬性爲null。然而,我可以說,在我自己的情況下(導致我這個問題的那個),問題是我的孩子MenuItem s是模板,因此在Parent屬性中不包含非空值。請注意,此評論爲the documentation for the FrameworkElement.Parent property

對於模板,模板的Parent最終將爲null。要通過這一點並將其擴展到實際應用模板的邏輯樹中,請使用TemplatedParent。

我發現遵循這個建議並不簡單。我的Parent房產從一開始就是null。但MenuItem對象的TemplatedParent屬性也是邏輯父項(由LogicalTreeHelper.GetParent()檢索)。

我最後要做的就是沿着視覺樹向上尋找確實有有一個邏輯父項的第一個父節點。此時,我能夠使用該節點的TemplatedParent屬性檢索實際的MenuItem父級。

我寫了一個簡單的輔助方法來概括這個。到目前爲止,我使用的唯一場景是MenuItem情景,我真的不知道這是否會在其他情況下需要。但它適用於我,似乎是一個很好的起點,以防我遇到與其他子對象(或其他任何人)類似的問題。

寫成擴展方法,它看起來像這樣:

public static T GetTemplatedParent<T>(this FrameworkElement o) 
    where T : DependencyObject 
{ 
    DependencyObject child = o, parent = null; 

    while (child != null && (parent = LogicalTreeHelper.GetParent(child)) == null) 
    { 
     child = VisualTreeHelper.GetParent(child); 
    } 

    FrameworkElement frameworkParent = parent as FrameworkElement; 

    return frameworkParent != null ? frameworkParent.TemplatedParent as T : null; 
} 

這讓我檢索任何模板MenuItem對象父MenuItem對象,而無需引入任何其他對象(很明顯,我可能已經解決這個問題僅僅是通過初始化某個靜態字段並獲取它的值,但這非常hacky&hellip;我想要更通用和可靠的東西)。