2012-01-25 13 views
2

menuitemコレクションでcurrentItemを選択する方法を教えてください。リストボックスと同じように。私はcollectionViewSourceでコレクションをラップしようとしましたが、それはそのような運がないことをもたらしました。wpfでの現在のMenuItemの選択

ありがとうございます。

答えて

0

ListBoxのItemsSourceに複合エンティティの汎用リストが設定されている場合、ListBox.SelectedValueを使用すると、現在選択されているデータが表示されます。例えば

:のContextMenuとメニューから派生

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

Iあなたは私の質問を忘れてしまったと思う。私はwpfのmenuitemsを指しています。リストボックスではありません。私はリストボックスでその機能を認識しています。しかし、もし私がmenuitemコレクションで似たようなことをすることができるかどうかを知りたい。 –

2

MenuBase、のSelectedItemの概念を含んでいないのItemsControlは、継承します。これは、ListBoxが追加するものです。

ただし、ItemsControl.ItemTemplateはあります。それは素晴らしいです。

オプションは、ItemTemplateをToggleButtonにすることです。これはあなたにいくつかのことを与えます。本来、ToggleButtonsはIsCheckedプロパティを使用して選択されたように見えることがあります。次に、ViewModelのコマンドにバインドできるCommandプロパティがあります。あなたはの線に沿って何かを持っている場合

ので、:

<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は、トグルボタンに表示するプロパティです。コマンドパラメータは、テンプレートが "{Binding}"以上を使用して折り返しているデータ項目にバインドしています。コマンドは実際にはメニューの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によってバインドされた項目のアンカーとして機能します。リンクされた記事は理由を説明します。

次に、2つのオブジェクトを互いに比較するコンバータが必要です。

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のから選択した項目を取り、トグルボタンがバインドされているものと比較しますバインディング。 2つのオブジェクトが一致する場合、ボタンはクリック/選択されて表示されます。一致しない場合、ボタンは選択されていません。

私はそのBindingProxyと私のコンバータを同じ名前空間に持つことになります。必ずしもそうする必要はありません。私はたいていプログラムしなければならない "Xaml Trick"クラスの名前空間を持っているだけです。

これは大量に消化するもので、何かを明確にすることができてうれしいです。

「ToggleButton」の外観が気に入らない場合は、いつでも完全に違って見えるようにスタイルを設定できます。 ToggleButtonを購入することは、 "IsChecked"プロパティとCommandプロパティです。 ContentTemplateを好みのように見せることができます。これにより、メニューのスタイルを自由に設定できます。

0

あなたがcurrentSelectedItemを表し(分離コードファイルまたはViewModelにのような)あなたのcontextfileでプロパティを持っているなら、あなたはあなたのXAMLに次のように書くことができますが:

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

分離コード/ ViewModelに

public MyType MyCurrentSelectedItem { get; set; } 
関連する問題