3

I have the Output something like Windows 8 Start Menu.

Here is screen-shot of my Output:

enter image description here

I have successfully got that output by getting help from this question.

XAML for achieving the below output:

<ItemsControl ItemsSource="{Binding MenuCategories}" >

    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel IsItemsHost="True" Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Grid >
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>

                <TextBlock Text="{Binding Title}" FontSize="30" />

                <ListBox Grid.Row="1" x:Name="lst" ItemsSource="{Binding Design_Master_TileItem}" BorderThickness="0"
                         SelectedItem="{Binding DataContext.SelectedTile, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Page}}}"
                         helpers:SingleSelectionGroup.SelectionGroup="Group">

                    <ListBox.ItemsPanel>
                        <ItemsPanelTemplate>
                            <WrapPanel IsItemsHost="True" Orientation="Vertical" MaxHeight="{Binding ElementName=lst, Path=ActualHeight}"/>
                        </ItemsPanelTemplate>
                    </ListBox.ItemsPanel>

                    <ListBox.Resources>
                        <Style TargetType="{x:Type ListBoxItem}">
                            <Setter Property="Width" Value="250" />
                            <Setter Property="Height" Value="125" />
                            <Setter Property="Margin" Value="2.5" />
                            <Setter Property="Padding" Value="2.5" />
                            <Setter Property="Background" Value="{Binding Background, Converter={StaticResource stringToBrushConverter}}" />
                            <Setter Property="Foreground" Value="White" />
                            <Setter Property="VerticalContentAlignment" Value="Bottom" />
                            <Style.Triggers>
                                <Trigger Property="IsSelected" Value="True">
                                    <Setter Property="Foreground" Value="{Binding Background, Converter ={StaticResource stringToBrushConverter}}" />
                                </Trigger>
                                <Trigger Property="IsKeyboardFocusWithin" Value="True">
                                    <Setter Property="IsSelected" Value="True"></Setter>
                                </Trigger>
                            </Style.Triggers>
                        </Style>
                    </ListBox.Resources>

                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal" Height="125" Width="250">
                                <Path Data="{Binding ImageData}"  VerticalAlignment="Center" 
                                      Stretch="Uniform" Fill="{Binding Foreground, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"
                                      Width="68" Height="68" Margin="10" RenderTransformOrigin="0.5,0.5">
                                    <Path.RenderTransform>
                                        <TransformGroup>
                                            <TransformGroup.Children>
                                                <RotateTransform Angle="0" />
                                                <ScaleTransform ScaleX="1" ScaleY="1" />
                                            </TransformGroup.Children>
                                        </TransformGroup>
                                    </Path.RenderTransform>
                                </Path>
                                <TextBlock Text="{Binding Title, Converter={StaticResource spaceToNewLineConverter}}" VerticalAlignment="Top" 
                                           Margin="40,10,10,10" FontSize="24" Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"/>
                            </StackPanel>
                        </DataTemplate>
                    </ListBox.ItemTemplate>

                </ListBox>
            </Grid>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

So, from the above code you might have understood that Group and Ledger are two items of listbox1. and other four are the items of listbox2.

Requirements:

Suppose, ItemA1 is selected in listboxA.

Case1: New Behavior

If ListBoxA does not have any items on the right side of Item1, then when I press right arrow key the focus should move to the ItemB1 of listboxB. Likewise if ItemA2 of listboxA is selected then the focus should move to the ItemB2 of ListBoxB.

Case2: Default Behavior

If ListBoxA has some items on the right hand side of ItemA1, then that item should be selected by pressing right arrow key. I have this behavior by default but I don't want to disturb it. I mean while implementing Case1 I don't want to loose the default behavior.

Community
  • 1
  • 1
Vishal
  • 6,238
  • 10
  • 82
  • 158
  • Unfortunately, I can not say exactly, but try add this Style to `ListBox`: ` – Anatoliy Nikolaev Mar 06 '14 at 06:44
  • Nope, you have mis-understood my question completely. The ListBox's ItemsPanel is set to WrapPanel with Orientation = Vertical. Now read the requirements section in question. I think you will now know what I want. – Vishal Mar 06 '14 at 18:52
  • Sorry that did not understand the question again, but I had warned in advance that I can not say for sure. I think it will be hard to do, because you have one `ListBox` in DataTemplate and while working to get access to multiple `ListBox`. Yes, this can be done through a large and ugly code, and by the algorithm, which should take into account the elements on each side. Therefore, if you have an alternative I suggest to find her. If not, I'll take this challenge and I can not say exactly when it will finish. And yet, if you want me to start doing the task, please let me a link to your project. – Anatoliy Nikolaev Mar 07 '14 at 04:21
  • Another question: `Likewise if ItemA2 of listboxA is selected then the focus should move to the ItemB2 of ListBoxB.` and `If ListBoxA has some items on the right hand side of ItemA1, then that item should be selected by pressing right arrow key.` - What's the difference between them? This is not the same behavior? – Anatoliy Nikolaev Mar 07 '14 at 05:21
  • I have mentioned that because see the sentence after word `and` in your comment, which is the default behavior. and the sentence before `and` is what I want to achieve without loosing the default behavior. In short forget about the Requirements section all-together and keep in mind that I want the behavior just like windows 8 start screen. – Vishal Mar 07 '14 at 05:38
  • Yes, If you become free then have a look at the project files below : Database Files : https://drive.google.com/file/d/0B5WyqSALui0bTmZ3S1lDM2lvdG8/edit?usp=sharing Project : https://drive.google.com/file/d/0B5WyqSALui0bWDhsbHltb2VhU3M/edit?usp=sharing – Vishal Mar 07 '14 at 05:49
  • Unfortunately, I did not work with Windows 8, and my studio is not open your project, because it is lower version. When there is time, I will try to reproduce it on my micro project but I can not exactly promise. – Anatoliy Nikolaev Mar 07 '14 at 06:11
  • I was not able to do it and here's why. As I understand it, you need to save the previously `SelectedIndex` in the `ListBox`, then to choose his own in the next `ListBox`. So, there is no property in ItemsControl like `SelectedIndex` or `SelectedItem`, accordingly, we do not know which is currently selected `ListBox`, to keep it current `SelectedIndex`. As an alternative - use `ListBox` instead of the `ItemsControl`, but then there will be a general confusion about the Focus, because it can be at the same time only one control with Focus (I already tried). – Anatoliy Nikolaev Mar 07 '14 at 10:52
  • It's OK, thanks for trying to help me. Can you find any alternative way to do it? – Vishal Mar 07 '14 at 12:47
  • No, I already tried. For me, so I do not see anything wrong in your behavior by default. – Anatoliy Nikolaev Mar 07 '14 at 12:56
  • 1
    @Vishal your current xaml code is also working only you need to add KeyboardNavigation.DirectionalNavigation="Continue" KeyboardNavigation.TabNavigation="Continue" to listbox http://prntscr.com/48gbbp try this may be it will save your efforts for new code – Heena Aug 01 '14 at 10:42
  • 1
    @HeenaPatil Thanks, for the above comment. I have just tried what you mentioned in the comment. But I get some problems while I use your code. When I press arrow keys it looks to work fine, but 1. if first item of first listbox is seleected then, if I press left arrow key, I get a red border around that listbox. 2. If first Item of any listbox is selected andd I press up arrow key then focus goes to the control above i.e. menu is focused. – Vishal Aug 01 '14 at 11:31
  • have you set focusvisualstyle to Listbox and Itemscontrol ? try setting Focusable= false to listbox and itemscontrol and remove focusvisualstyle = {x:null}..your code works perfect here. – Heena Aug 01 '14 at 11:39
  • @HeenaPatil Sorry to say, but I have already set Focusable="false". Also I don't have focusvisual style in my code. Still it does not work properly. – Vishal Aug 01 '14 at 11:45
  • @Vishal For 2 :Set KeyboardNavigation.DirectionalNavigation="Cycle" to ItemsControl and For 1: i dont understand why this red color border is coming is your listbox has scrollviwer..must be some another control taking focus here. – Heena Aug 01 '14 at 11:53
  • 1
    Yes, Now it works fine. But if I don't want to Cycle then what should I do? I mean if last Item is selected and I press down arrow key then I don't want to move focus to the first item. – Vishal Aug 01 '14 at 11:58
  • 1
    @HeenaPatil Got it. I set KeyBoardNavigation.DirectionalNavigation="Contained" on ItemsControl and it works as expected. Please post the above comments as answer and I will accept it. – Vishal Aug 01 '14 at 12:02
  • 1
    @AnatoliyNikolaev Please take a look at simple solution provided by Heena Patil. It might help you in future projects. – Vishal Aug 02 '14 at 18:41

2 Answers2

3

Your Current xaml code working fine here.. Please refer this link for KeyBoardNavigation Keyboardnavigation

You need to add only KeyboardNavigation.DirectionalNavigation="Continue" KeyboardNavigation.TabNavigation="Continue" to listbox and it works as expected.

   <ItemsControl KeyboardNavigation.DirectionalNavigation="Contained" Grid.Row="1" Focusable="False"  >
        ...

        <ListBox Grid.Row="1" x:Name="lst" KeyboardNavigation.DirectionalNavigation="Continue" KeyboardNavigation.TabNavigation="Continue"   BorderThickness="0"/>
    ..

   </ItemsControl>
Heena
  • 8,450
  • 1
  • 22
  • 40
2

Moving the focus from one ListBox to another within various items requires difficult logic. Instead you can use a single ListBox with grouping based on the Header. The GroupStyle Panel can be changed to stackpanel with horizontal orientation to achieve your UI. I tried like that and the focus works as expected,

<ListBox ItemsSource="{Binding Source={StaticResource source}}" DisplayMemberPath="Name">
        <ListBox.GroupStyle>
            <GroupStyle>
                <GroupStyle.HeaderTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Name}"/>
                    </DataTemplate>
                </GroupStyle.HeaderTemplate>
                <GroupStyle.Panel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal" />
                    </ItemsPanelTemplate>
                </GroupStyle.Panel>
            </GroupStyle>
        </ListBox.GroupStyle>
    </ListBox>
Jawahar
  • 4,775
  • 1
  • 24
  • 47
  • Can you post a sample? Because I get a blank listBox in my Output. – Vishal Aug 01 '14 at 09:10
  • 1
    Please try this sample. https://db.tt/UnSN74Oe [Accept the answer if it helps you] – Jawahar Aug 01 '14 at 09:31
  • I have made some changes to your sample project. I have uploaded it : https://drive.google.com/file/d/0B5WyqSALui0bXzdtWFVMYnpEWXM/edit?usp=sharing But I got a small problem here. How do I decrease the space between two items of same group on its left & right side? Also I want to increase the space between two different groups. – Vishal Aug 01 '14 at 09:49
  • 1
    Margin to ListBoxItem in ContainerStyle will control the spacings between items. Margin to WrapPanel will control the spacing between two groups. https://db.tt/UnSN74Oe Please accept the answer. – Jawahar Aug 01 '14 at 10:22