ListBox Code behind SetSelected called only when selecting item with right mouse button
Hi,
I'm trying to make a ListBox containing some custom items with a ViewModel code-behind.
My code and XAML are quite similar to the QuestLog Noesis sample, but I got that very strange behaviour:
My property for selecting the current listbox item is called only when clicking on right mouse button, left mouse button does nothing. and I don't understand why.
Here is my listBox on XAML side :
And here is my ViewModel implementation (simplified) :
Where the ViewModel deelecration is (also simoplified) :
When i set a breakpoint in the SetSelectedLookTopLeft method, if I left click on a listbox item, nothing happens, if I right click on the item, it's selected and the breakpoint is reached.
What can I do to be able to select items on left mouse click ??
Thanks a lot,
Frank
I'm trying to make a ListBox containing some custom items with a ViewModel code-behind.
My code and XAML are quite similar to the QuestLog Noesis sample, but I got that very strange behaviour:
My property for selecting the current listbox item is called only when clicking on right mouse button, left mouse button does nothing. and I don't understand why.
Here is my listBox on XAML side :
Code: Select all
<ControlTemplate x:Key="Car4LooksItemTemplate" TargetType="{x:Type ListBoxItem}">
<StackPanel Orientation="Vertical">
<Button Width="130" Height="137" Foreground="Red" BorderBrush="Red" Background="#80F2F2F2" Opacity="1.0" RenderTransformOrigin="0.5,0.5" VerticalAlignment="Center" HorizontalAlignment="Center">
<StackPanel Width="116" Height="134" Background="{StaticResource BandeauColor}" Orientation="Horizontal" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Canvas Width="85" Height="130" Background="{StaticResource BandeauColor}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Rectangle Width="14" Height="14" Canvas.Left="-25" Fill="{Binding DefaultColor}" Stroke="{Binding DefaultColor}" StrokeThickness="0" Margin="90,19,0,0" />
<Viewbox Width="85" Height="95" Canvas.Top="17">
<Image Source="{Binding Image}" RenderTransformOrigin="0.5,0.5">
<Image.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="270"/>
<TranslateTransform/>
</TransformGroup>
</Image.RenderTransform>
</Image>
</Viewbox>
</Canvas>
<TextBlock Text="{Binding Name}" TextAlignment="Center" Width="100" Height="12" Margin="-40,0,0,0" FontSize="10" RenderTransformOrigin="0.5,0.5" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="#FF000000" Background="#00000000" FontWeight="Bold" TextTrimming="CharacterEllipsis">
<TextBlock.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="270"/>
</TransformGroup>
</TextBlock.RenderTransform>
</TextBlock>
<TextBlock Text="{Binding Number}" TextAlignment="Center" Width="100" Height="13" Margin="-85,0,0,0" FontSize="11" RenderTransformOrigin="0.5,0.5" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="#FF808080" Background="#00000000" FontWeight="Bold">
<TextBlock.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="270"/>
</TransformGroup>
</TextBlock.RenderTransform>
</TextBlock>
</StackPanel>
</Button>
<Rectangle Fill="Black" Margin="0,0,0,0" Stroke="Black" Width="70" Height="2" HorizontalAlignment="Center" />
</StackPanel>
</ControlTemplate>
<Style x:Key="Car4LooksItemStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="Focusable" Value="False"/>
<Setter Property="Template" Value="{StaticResource Car4LooksItemTemplate}"/>
</Style>
<ControlTemplate x:Key="Template.ListBox" TargetType="ListBox">
<ScrollViewer Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" Focusable="False">
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
<Style x:Key="Car4LooksListStyle" TargetType="{x:Type ListBox}">
<Setter Property="SelectionMode" Value="Single"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Hidden"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden"/>
<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
<Setter Property="VirtualizingPanel.VirtualizationMode" Value="Recycling"/>
<Setter Property="VirtualizingPanel.ScrollUnit" Value="Pixel"/>
<Setter Property="KeyboardNavigation.DirectionalNavigation" Value="Contained"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Template" Value="{StaticResource Template.ListBox}"/>
</Style>
(...)
<ListBox x:Name="TopLeftMakeupSelector"
Style="{StaticResource Car4LooksListStyle}"
ItemContainerStyle="{StaticResource Car4LooksItemStyle}"
ItemsSource="{Binding LooksTopLeft}"
SelectedItem="{Binding SelectedLookTopLeft}"
DisplayMemberPath="Name"
Height="540"
Width="136">
</ListBox>
Code: Select all
////////////////////////////////////////////////////////////////////////////////////////////////////
struct ViewModel::Look : public BaseComponent
{
public:
String Name;
Ptr<ImageSource> Image;
String Number;
String Description;
Ptr<Brush> DefaultColor;
private:
NS_IMPLEMENT_INLINE_REFLECTION(Look, BaseComponent)
{
NsProp("Name", &Look::Name);
NsProp("Image", &Look::Image);
NsProp("Number", &Look::Number);
NsProp("Description", &Look::Description);
NsProp("DefaultColor", &Look::DefaultColor);
}
};
ViewModel::ViewModel()
{
_LooksTopLeft = *new ObservableCollection<Look>();
Ptr<ImageSource> image0 = *new BitmapImage("5eac6aeea60a650017b21177-compressed.png");
Ptr<ImageSource> image1 = *new BitmapImage("5eac6b63a60a650017b211af-compressed.png");
Ptr<Brush> color0 = *new SolidColorBrush(Color::Red);
Ptr<Brush> color1 = *new SolidColorBrush(Color::Green);
{
Ptr<Look> q = *new Look();
q->Name = "EYES TO KILL";
q->Image = image0;
q->Description = "Ldolor ac leo convallis";
q->Number = "12";
q->DefaultColor = color0;
_LooksTopLeft->Add(q);
}
{
Ptr<Look> q = *new Look();
q->Name = "NEO NUDE BLUSH";
q->Image = image1;
q->Description = "Nullam volutpat felis";
q->Number = "26";
q->DefaultColor = color1;
_LooksTopLeft->Add(q);
}
_selectedLookTopLeft = _LooksTopLeft->Get(0);
}
(...)
////////////////////////////////////////////////////////////////////////////////////////////////////
void ViewModel::SetSelectedLookTopLeft(Look* value)
{
if (_selectedLookTopLeft != value)
{
_selectedLookTopLeft = value;
OnPropertyChanged("SelectedLookTopLeft");
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ViewModel::Look* ViewModel::GetSelectedLookTopLeft() const
{
return _selectedLookTopLeft;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
NS_BEGIN_COLD_REGION
NS_IMPLEMENT_REFLECTION(ViewModel)
{
NsProp("LooksTopLeft", &ViewModel::_LooksTopLeft);
NsProp("SelectedLookTopLeft", &ViewModel::GetSelectedLookTopLeft, &ViewModel::SetSelectedLookTopLeft);
}
Code: Select all
class ViewModel : public NoesisApp::NotifyPropertyChangedBase
{
public:
ViewModel();
private:
struct Look;
void SetSelectedLookTopLeft(Look* value);
Look* GetSelectedLookTopLeft() const;
Noesis::Ptr<Noesis::ObservableCollection<Look>> _LooksTopLeft;
Look* _selectedLookTopLeft;
NS_DECLARE_REFLECTION(ViewModel, NotifyPropertyChangedBase)
};
What can I do to be able to select items on left mouse click ??
Thanks a lot,
Frank
-
sfernandez
Site Admin
- Posts: 2984
- Joined:
Re: ListBox Code behind SetSelected called only when selecting item with right mouse button
You defined a ListBoxItem template that consists of a Button covering the entire item space, so everytime you click on the item you are clicking the Button, not selecting the ListBoxItem.
When you right-click on the item the Button is not handling the event (Click is only raised on left-clicks) and it reaches the ListBoxItem, so then it gets selected.
Is there any reason why you need to have a Button as the template for the ListBoxItem?
When you right-click on the item the Button is not handling the event (Click is only raised on left-clicks) and it reaches the ListBoxItem, so then it gets selected.
Is there any reason why you need to have a Button as the template for the ListBoxItem?
Re: ListBox Code behind SetSelected called only when selecting item with right mouse button
Hi sfernandez,
You're completely right, when replacing the button by a stack panel, I get the code-behind methods called, but I loose the "button pressing effect" when I select an item.
I suppose I can get back the effect by using some trigger-based field, but, as I'm a begginer in XAML, and using a button was a convinient shortcut to get this effect for me.
I will try to get back the pressing effect using some triggering code.
Thanks
You're completely right, when replacing the button by a stack panel, I get the code-behind methods called, but I loose the "button pressing effect" when I select an item.
I suppose I can get back the effect by using some trigger-based field, but, as I'm a begginer in XAML, and using a button was a convinient shortcut to get this effect for me.
I will try to get back the pressing effect using some triggering code.
Thanks
-
sfernandez
Site Admin
- Posts: 2984
- Joined:
Re: ListBox Code behind SetSelected called only when selecting item with right mouse button
The ListBoxItem template can (should) have triggers (or visual states) to represent the different states of the control: IsMouseOver, IsSelected, IsFocused...
For example, our ListBoxItem template does the following: https://github.com/Noesis/Managed/blob/ ... 1788-L1807
For example, our ListBoxItem template does the following: https://github.com/Noesis/Managed/blob/ ... 1788-L1807
Re: ListBox Code behind SetSelected called only when selecting item with right mouse button
Thanks,
It seems I have some control using triggers like the ones your're pointing out.
Nevertheless, I'd like to simulate a "button pushed" status when the user is cliking on an item, and I can't find a property I can use with a trigger like "IsMouseCliked" telling the user is left clicking on the item. Is there one ?
It seems I have some control using triggers like the ones your're pointing out.
Nevertheless, I'd like to simulate a "button pushed" status when the user is cliking on an item, and I can't find a property I can use with a trigger like "IsMouseCliked" telling the user is left clicking on the item. Is there one ?
-
sfernandez
Site Admin
- Posts: 2984
- Joined:
Re: ListBox Code behind SetSelected called only when selecting item with right mouse button
ListBoxItem does not provide an IsPressed property, but you can use an EventTrigger with MouseDown/MouseUp events to fire an animation that can change the appearance accordingly.
Re: ListBox Code behind SetSelected called only when selecting item with right mouse button
I finally made this work using :
Thanks a lot for the help
Code: Select all
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDown" >
<ei:ChangePropertyAction PropertyName="Background" Value="{DynamicResource Brush.Item.Over}"/>
</i:EventTrigger>
<i:EventTrigger EventName="MouseUp" >
<ei:ChangePropertyAction PropertyName="Background" Value="{DynamicResource Brush.Item.UnSelected}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
-
sfernandez
Site Admin
- Posts: 2984
- Joined:
Re: ListBox Code behind SetSelected called only when selecting item with right mouse button
You're welcome, marking this as solved.
Who is online
Users browsing this forum: Google [Bot] and 3 guests