2012-01-25 46 views
2

如何在menuitem集合中選擇currentItem。就像人們會用列表框一樣。我試圖在collectionViewSource中包裝這個集合,然而那並沒有帶來這樣的運氣。在wpf中選擇當前MenuItem

在此先感謝。

回答

0

如果ListBox將其ItemsSource設置爲複雜實體的通用列表,則使用ListBox.SelectedValue將獲取當前選定的數據。

例如:

public partial class NameListView : Window 
{ 
    /// <summary> 
    /// Constructor 
    /// </summary> 
    public NameListView() 
    { 
     List<string> names = new List<string>(); 
     names.Add("John Doe"); 
     names.Add("Jane Doe"); 

     lbNameList.ItemsSource = names; 
    } 

    /// <summary> 
    /// Selection changed event handler for ListBox lbNameList 
    /// </summary> 
    void lbNameList_SelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     if (e.AddedItems.Count > 0) 
     { 
      string currentValue = lbNameList.SelectedValue.ToString(); 
      MessageBox.Show("Currently selected value: " + currentValue); 
     } 
    } 
} 
+1

我想你錯過了我的問題。我指的是wpf中的menuitems。不是列表框。我知道與列表框的功能。但是我想知道如果我能用menuitem集合做類似的事情。 –

2

的MenuBase,其文本菜單和菜單從派生,繼承ItemsControl的,其不包括的SelectedItem的概念。這是ListBox添加的內容。

但是,您確實擁有ItemsControl.ItemTemplate。這真棒。

一種選擇是讓你的ItemTemplate成爲一個ToggleButton。這給你一些事情。本質上,ToggleButtons可以看起來像使用它們的IsChecked屬性進行選擇。其次,他們有一個Command屬性,您可以綁定到ViewModel中的命令。

所以,如果你有沿着線的東西:

<Menu ItemsSource="{Binding ThingsToBindTo}"> 
     <Menu.ItemTemplate> 
      <DataTemplate> 
       <Grid> 
        <Grid.Resources> 
         <conv:BindingProxy x:Key="proxy" Data="{Binding}" /> 
        </Grid.Resources> 
        <ToggleButton Content="{Binding NameOrLabel}" CommandParameter="{Binding}" Command="{Binding Path=DataContext.SelectThingCommand, RelativeSource={RelativeSource AncestorType=Menu}}" > 
         <ToggleButton.IsChecked> 
          <Binding Mode="OneWay" Path="DataContext.SelectedThing" RelativeSource={RelativeSource AncestorType=Menu}"> 
           <Binding.Converter> 
            <conv:ComparisonConverter CompareTo="{Binding Source={StaticResource proxy}, Path=Data}" /> 
           </Binding.Converter> 
          </Binding> 
         </ToggleButton.IsChecked> 
        </ToggleButton> 
       </Grid> 
      </DataTemplate> 
     </Menu.ItemTemplate> 
    </Menu> 

所以這是一個有點複雜。

按照常規,您綁定到項目列表。 ThingsToBindTo應該是你的列表。然後你開始定義你的模板。 NameOrLabel是您想要在切換按鈕上顯示的任何屬性。命令參數通過使用「{綁定}」以外的任何內容綁定到模板正在包裝的數據項。該命令實際上在您的Menu的DataContext上,這就是爲什麼使用RelativeSource的原因。

這是說的是你要傳遞一個命令,那只是被點擊的東西。實際上,您正在選擇您點擊的按鈕。然後,你的命令只需要在你的ViewModel中設置一個SelectedThing屬性,它等於傳給它的任何東西。希望你已經實現了一個實現ICommand的類來創建委託命令。如果你不這樣做,那裏有很多關於如何去做的文章。如果你不知道如何,請對這篇文章發表評論,我將添加源代碼來完成它。

然後,我們有「IsChecked」壞男孩。我們實際上在那裏做了一個有約束力的約束。這是更復雜的部分,但它允許DataTemplated項目在轉換器中實際綁定到它自己。

首先,你需要代理對象,這是在這裏解釋: http://tomlev2.wordpress.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/

很容易實現。一旦完成,網格中的BindingProxy資源就可以工作,並且可以充當返回到由DataTemplate綁定的項目的錨點。鏈接的文章解釋了原因。

然後,您需要一個轉換器,將兩個對象相互比較。

public class ComparisonConverter : DependencyObject, IValueConverter 
{ 
    public object CompareTo 
    { 
     get { return (object)GetValue(CompareToProperty); } 
     set { SetValue(CompareToProperty, value); } 
    } 

    public static readonly DependencyProperty CompareToProperty = 
     DependencyProperty.Register("CompareTo", typeof(object), typeof(ComparisonConverter), new UIPropertyMetadata(null)); 

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     if (CompareTo != null) 
     { 
      return CompareTo.Equals(value); 
     } 
     else 
     { 
      return false; 
     } 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

因此,現在綁定將從菜單的DataContext中選取項目,並將其與ToggleButton所綁定的任何項目進行比較。如果兩個對象匹配,則會顯示單擊/選擇按鈕。如果它們不匹配,則該按鈕看起來不被選中。

所以我碰巧在同一個命名空間中有BindingProxy和我的轉換器。你不一定非得這樣做。我通常有一個名爲「Xaml Trick」的類,我必須編程。

這是很多消化,我很樂意澄清任何事情。

另外一件事......如果你不喜歡「ToggleButton」的外觀,你總是可以讓它們看上去完全不同。有一個ToggleButton購買你的東西是「IsChecked」屬性和Command屬性。您可以使ContentTemplate看起來像您想要的任何東西,這使您在菜單樣式中有很大的自由度。

0

如果你在你的contextfile屬性(如代碼隱藏文件或視圖模型)表示currentSelectedItem那麼你可以寫在你的XAML如下:

<ListView x:Name="MyList" 
      ItemsSource="MySource" 
      SelectedItem="{Binding Path=MyCurrentSelectedItem}" IsSynchronizedWithCurrentItem="True"> 

代碼隱藏/視圖模型

public MyType MyCurrentSelectedItem { get; set; }