Page 1 of 1

Focus event managerment

Posted: 05 Apr 2016, 10:08
by lomoonmoonbird
Hi
I have a user interface, there are three layers in horizontal, each layer has few buttons ,listbox and tabcontrol, i noticed that when changing focus using keyboard or remote control,the focus on each control was not expected as what i want, for example,when i move out from listbox which contains few buttons to another control,and back to the listbox,the focus was not set where it was,and the effect was different too. another example is how i just want to move the focus out into another control when i click up or down keyboard rather than click left or right keyboard until to the edge of the control, that is , i have a listbox which contains few buttons,above this listbox is a tabcontrol, when i scroll the listbox horizontally to the edge,the focus should not be out of the listbox,but when i press up button ,the focus should be moved to tabcontrol,so it is with the tabcontrol.

Do i need to write extra codes to manage the focus event so that the focus behaviour can be as what i describe above?

this is my ui code:
<Grid 
      x:Class="putaogamedemo.page1"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="clr-namespace:putaogamedemo"
      mc:Ignorable="d" 
      xmlns:vm="clr-namespace:putaogame.ViewModels" >
    

    <Grid.Resources>
        <vm:MytabViewModel x:Key="MytabViewModel"></vm:MytabViewModel>
        <DataTemplate x:Key="ItemTemplate">
            <Button Content="{Binding}" Foreground="White" />
        </DataTemplate>

        <DataTemplate x:Key="SelectedTemplate">
            <Button Content="{Binding}" Foreground="Red" />
        </DataTemplate>

        <DataTemplate x:Key="UnSelectedTemplate">
            <Button Content="{Binding}" Foreground="White" />
        </DataTemplate>

        <Style TargetType="{x:Type ListBoxItem}" x:Key="ContainerStyle">
            <Setter Property="ContentTemplate" Value="{StaticResource ItemTemplate}" />
            <Style.Triggers>
                <Trigger Property="IsFocused" Value="True">
                    <Setter Property="ContentTemplate" Value="{StaticResource SelectedTemplate}" />
                </Trigger>
            </Style.Triggers>

        </Style>

        <Style TargetType="{x:Type Button}" x:Key="ContainerStyle1">
            <Setter Property="ContentTemplate" Value="{StaticResource ItemTemplate}" />
            <Style.Triggers>
                <Trigger Property="IsFocused" Value="True">
                    <Setter Property="ContentTemplate" Value="{StaticResource SelectedTemplate}" />
                </Trigger>

            </Style.Triggers>

        </Style>

    </Grid.Resources>

    <Viewbox Stretch="UniformToFill">
        <Grid>
            <Canvas Width="1820" Height="1080" Margin="-10,-10,10,10">
                <Image x:Name="SpaceBg" Source="bg1.jpg" Stretch="Fill" Height="1396" Width="2240" Canvas.Left="-251" Canvas.Top="-160">

                </Image>
            </Canvas>
            <!--<Canvas Width="1800" Height="1080">
                <Image x:Name="BigPlanet" Source="BigPlanet.png" Stretch="Fill" Height="1080" Width="800" Canvas.Left="990" Canvas.Top="85">

                </Image>
            </Canvas>
            <Canvas Width="1800" Height="1080">
                <Image x:Name="CloseUpPlanet" Source="CloseUpPlanet.png" Stretch="Fill"  Canvas.Right="0" Canvas.Bottom="0">

                </Image>
            </Canvas>-->
        </Grid>
    </Viewbox>

    <StackPanel Name="mypanel" Margin="100,10,10,10">

        <Grid HorizontalAlignment="Center" VerticalAlignment="Center" >


            <StackPanel Grid.Row="0" Grid.Column="0" Margin="-342,98,652,-314" RenderTransformOrigin="0.472,0.754" Width="492.19">
                <StackPanel.Background>
                    <ImageBrush ImageSource="bg2.jpg"/>
                </StackPanel.Background>
                <TextBlock Height="343.3" Opacity=".4" FontSize="30" Foreground="White" Background="#FF575723" Margin="15,18,15,16">                  
                    "I promised to love him and let him eat from my golden plate,
                    drink from my golden cup, and sleep on my golden bed."
                </TextBlock>
                <Button HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Opacity=".5" Style="{StaticResource ContainerStyle1}" Content="setting" Margin="18,16,18,-100"/>
                <Button VerticalAlignment="Bottom" Opacity=".5" Style="{StaticResource ContainerStyle1}" Content="detail" BorderThickness="0" Margin="18,100,18,18"/>
            </StackPanel>


            <TabControl Grid.Row="0"
        		Width="690" 
                
        		DataContext="{StaticResource MytabViewModel}" 
        		TabStripPlacement="Right"
        		KeyboardNavigation.DirectionalNavigation="Continue"
        		ItemsSource="{Binding Mytab}" HorizontalAlignment="Left" Margin="374.19,98,0,-314">
                <TabControl.Resources>
                    <Style TargetType="TabItem">
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="TabItem">
                                    <Border Name="Border" BorderThickness="1,1,1,0" BorderBrush="Gainsboro" CornerRadius="4,4,0,0" Margin="2,0">
                                        <ContentPresenter x:Name="ContentSite"
                                                          VerticalAlignment="Center"
                                                          HorizontalAlignment="Center"
                                                          ContentSource="Header"
                                                          Margin="10,2">

                                        </ContentPresenter>

                                    </Border>

                                    <ControlTemplate.Triggers>

                                        <Trigger Property="IsSelected" Value="True">
                                            <Setter TargetName="Border" Property="Background" Value="LightSkyBlue"></Setter>
                                        </Trigger>
                                        <Trigger Property="IsSelected" Value="False">
                                            <Setter TargetName="Border" Property="Background" Value="GhostWhite"></Setter>
                                        </Trigger>
                                    </ControlTemplate.Triggers>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </TabControl.Resources>
                <TabControl.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Header}" Foreground="White" Background="Black" FontSize="10" />
                    </DataTemplate>
                </TabControl.ItemTemplate>
                <TabControl.ContentTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Content}" Foreground="White" Background="Black" FontSize="15" />
                    </DataTemplate>
                </TabControl.ContentTemplate>

            </TabControl>
        </Grid>
        <ListBox
                 SelectedItem="{Binding SelectedItem}" 
                 KeyboardNavigation.DirectionalNavigation="Continue"
                 ItemContainerStyle="{StaticResource ContainerStyle}"
                 x:Name="listbox"
                     Margin="183,500,392,10"
                     Background="White"
                 Opacity=".5"
                 ScrollViewer.VerticalScrollBarVisibility="Hidden"
                 ScrollViewer.HorizontalScrollBarVisibility="Hidden" 
                 ScrollViewer.CanContentScroll="True"
                 
                VerticalAlignment="Bottom">
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal"/>
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
            <Button x:Name="button1"  >
                <StackPanel>
                    <Image Source="jiangwei.png"/>
                    <TextBlock><Run Text="jiangwei"/></TextBlock>
                </StackPanel>

            </Button>

            <Button x:Name="button2" >
                <!--<Button.Resources>
                    <Style TargetType="Button">
                        <Setter Property="BorderBrush" Value="Red"></Setter>
                        <Style.Triggers>
                            <Trigger Property="IsFocused" Value="True">
                                <Setter Property="BorderBrush" Value="WhiteSmoke"></Setter>
                            </Trigger>
                        </Style.Triggers>
                    </Style>
                </Button.Resources>-->
                <StackPanel>
                    <Image Source="xushu.png"/>
                    <TextBlock><Run Text="xushu"/></TextBlock>
                </StackPanel>
            </Button>
            <Button x:Name="button3" >
                <StackPanel>
                    <Image Source="yujin.png"/>
                    <TextBlock><Run Text="yujin"/></TextBlock>
                </StackPanel>
            </Button>
            <Button x:Name="button4" >
                <StackPanel>
                    <Image Source="yuzhenren.png"/>
                    <TextBlock><Run Text="yuzhenren"/></TextBlock>
                </StackPanel>
            </Button>
            <Button x:Name="button5" >
                <StackPanel>
                    <Image Source="zhanghe.png"/>
                    <TextBlock><Run Text="zhanghe"/></TextBlock>
                </StackPanel>
            </Button>
            <Button x:Name="button6" >
                <StackPanel>
                    <Image Source="zhangliao.png"/>
                    <TextBlock><Run Text="zhangliao"/></TextBlock>
                </StackPanel>
            </Button>
            <Button x:Name="button7" >
                <StackPanel>
                    <Image Source="zhaoyun.png"/>
                    <TextBlock><Run Text="zhaoyun"/></TextBlock>
                </StackPanel>
            </Button>
            <Button x:Name="button8" >
                <StackPanel>
                    <Image Source="zhenmi.png"/>
                    <TextBlock><Run Text="zhenmi"/></TextBlock>
                </StackPanel>
            </Button>
            <Button x:Name="button9" >
                <StackPanel>
                    <Image Source="zhoutai.png"/>
                    <TextBlock><Run Text="zhoutai"/></TextBlock>
                </StackPanel>
            </Button>
            <Button x:Name="button10" >
                <StackPanel>
                    <Image Source="zhouyu.png"/>
                    <TextBlock><Run Text="zhouyu"/></TextBlock>
                </StackPanel>
            </Button>
            <Button x:Name="button11" >
                <StackPanel>
                    <Image Source="zhujue.png"/>
                    <TextBlock><Run Text="zhujue"/></TextBlock>
                </StackPanel>
            </Button>
            <Button x:Name="button12" >
                <StackPanel>
                    <Image Source="sunce.png"/>
                    <TextBlock><Run Text="sunce"/></TextBlock>
                </StackPanel>
            </Button>
        </ListBox>
    </StackPanel>
</Grid>

I appreciate your help, Thanks in advance. :)

Re: Focus event managerment

Posted: 06 Apr 2016, 10:46
by sfernandez
Hi,

Could you please post a screenshot of the user interface layout, so I can better understand the scenario and then explain what's the expected behavior?

Thank you.

Re: Focus event managerment

Posted: 06 Apr 2016, 13:36
by lomoonmoonbird
Hi

pic 1:

Image

the focus on the avatar "a" at first, when i press up button, it should be focused on checkbox1, but it moves to checkbox2,the black arrow is what i want , red error is not.

pic 2:

Image

when the focus on certain one of the avatar list,lets say on avatar "e",when i press up button ,it moves to checkboxx2,go ahead pressing up ,it will go to c2,b2,now i press down button,it will go to c2,checkbox2,but the final focus moves to avatar "c",it is not where i started.it should be focused on avatar e again,the black arrow is what i want, the red arrow is wrong.

I checked MSDN about Focus management, they mentioned Keyboard and FocusManager,or some base Class such as UIElement ,using MoveFocus or PredictFocus and anything else to manage that,and i noticed that noesis not implement FocusManager yet,so what should i do to manage the focus event so i can completely control how the focus moves.Thanks


this is my xaml:
<Grid 
      x:Class="putaogamedemo.page1"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="clr-namespace:putaogamedemo"
      mc:Ignorable="d" Height="544.24" Width="1002"
      
       >


  <Grid.Resources>
    <!--xmlns:vm="clr-namespace:putaogame.ViewModels"
    <vm:MytabViewModel x:Key="MytabViewModel"></vm:MytabViewModel>-->
        <DataTemplate x:Key="ItemTemplate">
            <Button Content="{Binding}" Foreground="White" Width="60" />
        </DataTemplate>

        <DataTemplate x:Key="SelectedTemplate">
            <Button Content="{Binding}" Foreground="Red" Width="60" />
        </DataTemplate>

        <DataTemplate x:Key="UnSelectedTemplate">
            <Button Content="{Binding}" Foreground="White" Width="60" />
        </DataTemplate>

        <Style TargetType="{x:Type ListBoxItem}" x:Key="ContainerStyle">
            <Setter Property="ContentTemplate" Value="{StaticResource ItemTemplate}" />
            <Style.Triggers>
                <Trigger Property="IsFocused" Value="True">
                    <Setter Property="ContentTemplate" Value="{StaticResource SelectedTemplate}" />
                </Trigger>
            </Style.Triggers>

        </Style>

        <Style TargetType="{x:Type Button}" x:Key="ContainerStyle1">
            <Setter Property="ContentTemplate" Value="{StaticResource ItemTemplate}" />
            <Style.Triggers>
                <Trigger Property="IsFocused" Value="True">
                    <Setter Property="ContentTemplate" Value="{StaticResource SelectedTemplate}" />
                </Trigger>

            </Style.Triggers>

        </Style>

    </Grid.Resources>
    <Grid.Background>
        <ImageBrush ImageSource="bg1.jpg" Stretch="UniformToFill"/>
    </Grid.Background>

    <!--<Viewbox Stretch="UniformToFill">
        <Grid>
            <Canvas Width="1820" Height="1080" Margin="-10,-10,10,10">
                <Image x:Name="SpaceBg" Source="bg1.jpg" Stretch="Fill" Height="1080" Width="1810" Canvas.Left="10" Canvas.Top="10"/>
            </Canvas>
        </Grid>
    </Viewbox>-->

  <Grid KeyboardNavigation.DirectionalNavigation="Continue" Opacity=".5" Background="White">
    <Grid.RowDefinitions>
      <RowDefinition Height="Auto" />
      <RowDefinition Height="100" />
      <RowDefinition />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
      <ColumnDefinition />
      <ColumnDefinition />
      <ColumnDefinition />
    </Grid.ColumnDefinitions>
    
    
    <GroupBox KeyboardNavigation.DirectionalNavigation="Continue" Name="box1" Header="No focus scope" Grid.Row="2" >
      <StackPanel KeyboardNavigation.DirectionalNavigation="Continue" Margin="4">
        <Button >a1</Button>
        <Button>b1</Button>
        <Button>c1</Button>
        
        <CheckBox KeyboardNavigation.DirectionalNavigation="Continue">CheckBox1</CheckBox>
      </StackPanel>
    </GroupBox>
    <GroupBox KeyboardNavigation.DirectionalNavigation="Continue" Name="box2" Header="WPF focus scope"  Grid.Column="1" Grid.Row="2">
      <StackPanel Margin="4">
        <Button>a2</Button>
        <Button>b2</Button>
        <Button>c2</Button>
        
        <CheckBox>CheckBox2</CheckBox>
      </StackPanel>
    </GroupBox>
    <GroupBox KeyboardNavigation.DirectionalNavigation="Continue" Name="box3" Header="My Focus Scope"  Grid.Column="2" Grid.Row="2" >
      <StackPanel Margin="4">
        <Button >a3</Button>
        <Button>b3</Button>
        <Button>c3</Button>
       
        <CheckBox>CheckBox3</CheckBox>
      </StackPanel>
    </GroupBox>
  </Grid>


    <ListBox
                 SelectedItem="{Binding SelectedItem}" 
                 KeyboardNavigation.DirectionalNavigation="Continue"
                 ItemContainerStyle="{StaticResource ContainerStyle}"
                 x:Name="listbox"
                     Margin="177.5,0,0,82"
                     Background="White"
                 Opacity=".5"
                 ScrollViewer.VerticalScrollBarVisibility="Hidden"
                 ScrollViewer.HorizontalScrollBarVisibility="Hidden" 
                 ScrollViewer.CanContentScroll="True"
                VerticalAlignment="Bottom" HorizontalAlignment="Left" Width="612">
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal"/>
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
        <Button x:Name="button1"  >
            <StackPanel>
                <Image Source="jiangwei.png"/>
                <TextBlock><Run Text="a"/></TextBlock>
            </StackPanel>

        </Button>

        <Button x:Name="button2" >
            <!--<Button.Resources>
                    <Style TargetType="Button">
                        <Setter Property="BorderBrush" Value="Red"></Setter>
                        <Style.Triggers>
                            <Trigger Property="IsFocused" Value="True">
                                <Setter Property="BorderBrush" Value="WhiteSmoke"></Setter>
                            </Trigger>
                        </Style.Triggers>
                    </Style>
                </Button.Resources>-->
            <StackPanel>
                <Image Source="xushu.png"/>
                <TextBlock><Run Text="b"/></TextBlock>
            </StackPanel>
        </Button>
        <Button x:Name="button3" >
            <StackPanel>
                <Image Source="yujin.png"/>
                <TextBlock><Run Text="c"/></TextBlock>
            </StackPanel>
        </Button>
        <Button x:Name="button4" >
            <StackPanel>
                <Image Source="yuzhenren.png"/>
                <TextBlock><Run Text="d"/></TextBlock>
            </StackPanel>
        </Button>
        <Button x:Name="button5" >
            <StackPanel>
                <Image Source="zhanghe.png"/>
                <TextBlock><Run Text="e"/></TextBlock>
            </StackPanel>
        </Button>
        <Button x:Name="button6" >
            <StackPanel>
                <Image Source="zhangliao.png"/>
                <TextBlock><Run Text="f"/></TextBlock>
            </StackPanel>
        </Button>
        <Button x:Name="button7" >
            <StackPanel>
                <Image Source="zhaoyun.png"/>
                <TextBlock><Run Text="g"/></TextBlock>
            </StackPanel>
        </Button>
        <Button x:Name="button8" >
            <StackPanel>
                <Image Source="zhenmi.png"/>
                <TextBlock><Run Text="h"/></TextBlock>
            </StackPanel>
        </Button>
        <Button x:Name="button9" >
            <StackPanel>
                <Image Source="zhoutai.png"/>
                <TextBlock><Run Text="i"/></TextBlock>
            </StackPanel>
        </Button>
        <Button x:Name="button10" >
            <StackPanel>
                <Image Source="zhouyu.png"/>
                <TextBlock><Run Text="j"/></TextBlock>
            </StackPanel>
        </Button>
        <Button x:Name="button11" >
            <StackPanel>
                <Image Source="zhujue.png"/>
                <TextBlock><Run Text="k"/></TextBlock>
            </StackPanel>
        </Button>
        <Button x:Name="button12" >
            <StackPanel>
                <Image Source="sunce.png"/>
                <TextBlock><Run Text="l"/></TextBlock>
            </StackPanel>
        </Button>
    </ListBox>

</Grid>

this is my Monobehaviour class:
using UnityEngine;
using Noesis;
using System.Collections;

public class behaviour : MonoBehaviour {

    // Use this for initialization
    Noesis.Button button1;
    Noesis.Grid root;
    Noesis.ListBox listbox;
    Noesis.StackPanel mypanel;
	void Start () {
        root = (Noesis.Grid)GetComponent<NoesisGUIPanel>().GetContent();
        //mypanel = (Noesis.StackPanel)root.FindName("mypanel");
        listbox = (Noesis.ListBox)root.FindName("listbox");
        
        button1 = (Noesis.Button)listbox.FindName("button1");
        Debug.Log(listbox);
        button1.Focus();
    }

    // Update is called once per frame
    void Update () {
	
	}
}

you can try this codes,Thanks :)

Re: Focus event managerment

Posted: 06 Apr 2016, 14:34
by sfernandez
Ok, I see what is happening now.

When you move focus using arrow keys, your are using directional navigation, which looks for the nearest control in the pressed direction.

In the first case, when focus was in avatar "a", pressing "UP" arrow key will look for a control with the minimum distance between its Bottom-Left corner and the Top-Left corner of the avatar control. That control is "CheckBox 2", so the behavior is correct.

In the second case, when pressing "UP" it occurs the same, the nearest Bottom-Left corner from avatar "e" Top-Left corner is again "CheckBox 2". When "DOWN" arrow is pressed it looks for the nearest Top-Left corner from "CheckBox 2" Bottom-Left corner, and that is avatar "c" control.

If you need to manage the focus yourself, you can attach a handler to PreviewKeyDown and KeyDown events, maybe in the window root container. If arrow keys were pressed, you can move focus as you wish and set the args.Handled to true to avoid that KeyboardNavigation does his job.

Re: Focus event managerment

Posted: 06 Apr 2016, 17:25
by lomoonmoonbird
Hi
Is there any sample or can you write some critical codes please, maybe you can implement it with my code above , because i do not have any clue, I will be grateful,thanks for your time :)

Re: Focus event managerment

Posted: 12 Apr 2016, 10:34
by sfernandez
Here is some code to handle the focus yourself:
    public partial class page1 : Grid
    {
        Button[] buttons = new Button[4];
        int btnIndex = 0;

        public page1()
        {
            InitializeComponent();

            Loaded += page1_Loaded;
        }

        void page1_Loaded(object sender, RoutedEventArgs e)
        {
            buttons[0] = (Button)FindName("btn1a");
            buttons[1] = (Button)FindName("btn2a");
            buttons[2] = (Button)FindName("btn3a");
            buttons[3] = (Button)FindName("button1");

            buttons[0].Focus();

            KeyDown += page1_KeyDown;
        }

        void page1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Left || e.Key == Key.Right || e.Key == Key.Up || e.Key == Key.Down)
            {
                // manage the focus manually...
                Debug.Log("Arrow key pressed: " + e.Key);

                // ...just for testing I move focus to some known controls
                btnIndex = (btnIndex + 1) % buttons.Length;
                buttons[btnIndex].Focus();

                // avoid automatic KeyboardNavigation when arrow keys are pressed
                e.Handled = true;
            }
        }
    }