views:

251

answers:

2

I have a Contextmenu with a ListBox inside. Whenever I right click my control and select a value from my contextmenu the last selected value stays marked and I can't select that value again.

The idea is, that I may select the same value within the COntextmenu in order to turn a property on or off.

Should be quite basic, what am I missing?

Many Thanks,

EDIT: Thanks for the responses. I have tried to apply your ideas without success. I think the major problem is that MenuItems of a contextmenu have no ItemSource to be bound to a collection (e.g. PossibleValues as in this example).

May I insert my code for clarification:

    <Border.ContextMenu>
      <ContextMenu>
       <ContextMenu.ItemContainerStyle>
         <Style TargetType="{x:Type MenuItem}">
           <Setter Property ="Template">
             <Setter.Value>
                <ControlTemplate TargetType="{x:Type MenuItem}">
                  <ContentPresenter x:name="Header" ContentSource="Header" RecognizesAccessKey="True"/>
                </ControlTemplate>
             </Setter.value>
           </Setter>
         </Style>
       <ContextMenu.ItemContainerStyle>
       <ListBox BorderThickness="0" Width="35" Margin="0"
                SelectedItem="{Binding Path=Volume, Mode=TwoWay}
                DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DataContext}" 
                ItemsSource="{Binding Path=PossibleValues}"/>
       </ContextMenu>
    </Border.ContextMenu>
+2  A: 

Why do you have a ListBox in your ContextMenu? A ListBox allows you to select one item out of a list (or multiple items, if enabled). An example is the list of files in Explorer.

A ContextMenu is an ItemsControl, ie. you can add an arbitrary number of items to it. So just add the items directly.

EDIT: Both the ContextMenu and MenuItem are ItemsControl. They both have an ItemsSource property. So you could have the following:

<ContextMenu
    DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DataContext}"
    ItemsSource="{Binding Path=PossibleValues}"/>

PossibleValues could be a collection of MenuItems. Each menuitem could look at follows (here in code), for example:

var menuItem = new MenuItem();
menuItem.Items.Add(new TextBlock { Text = "Something" });
menuItem.Command = DoSomethingCommand;
menuItem.CommandParameter = "identifier";

EDIT2: Try something like the following. As command you could use one of the many implementations from MVVM helper libraries, such as DelegateCommand<> from Prism or SimpleCommand from Cinch.

PossibleValues = new ObservableCollection<MenuItem>();

// null value
var nullMenuItem = new MenuItem();
nullMenuItem.Items.Add(new TextBlock { Text = "Null" });
nullMenuItem.Command = DoSomethingCommand;
nullMenuItem.CommandParameter = null;
PossibleValues.Add(nullMenuItem);

// Values one to nine
for (int i = 1; i < 9; i++)
{
    var menuItem = new MenuItem();
    menuItem.Items.Add(new TextBlock { Text = i.ToString() });
    menuItem.Command = DoSomethingCommand;
    menuItem.CommandParameter = i;
    PossibleValues.Add(menuItem);
}

As for your execute handler of the command, something along the lines of:

public void DoSomethingCommand_Execute(object commandParameter)
{
    this.SelectedNumber = commandParameter as int?;
    // Or whatever you actually want to do in response to the selection.
}
Daniel Rose
Daniel, as you can see from the code sample, the Contextmenu needs to select a value from a collection. I thought normal Contextmenu Items, can only apply a Command action only, since they wont support SelectedItem property, correct? I wonder if I should dig into the ListBox control to use a customized control for my needs after all, or if there is an easier approach to it.
Kave
Daniel, I really appreciate your help on this. I should have mentioned that PossibleValues is no more than a collection of type int? with values starting with null and 1 to 9. There wont be a need for any Command to do something else. What matters is what number has been selected by the user. The usecase is that the user selects a number from contextmenu and the selected possible number coming from PossibleValues modifies another property called Value in this example. Therefore I am still concerned about not having a SelectedItem property within the ContextMenu to update the Value Property.
Kave
But then again I am new to WPF, if my concern is unneccessary please forgive me. :)
Kave
A: 

This is the expected behaviour of a ListBox control - it doesn't matter that it's in a ContextMenu. A ListBox's default behaviour doesn't allow de-selection of items; what you probably want is either a regular chackable MenuItem, or a ListBox with complex selection modes enabled.

Dan Puzey
I have a feeling - as you pointed out - SelectionMode="Multiple" on my ListBox would exactly do what I want. Need to test later and will let you know. Thanks
Kave
hmm didnt work as expected. :( I need to play around with MenuItems after all.
Kave