- lomoonmoonbird
- Posts: 30
- Joined:
Focus event managerment
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:
I appreciate your help, Thanks in advance.
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:
Code: Select all
<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>
-
sfernandez
Site Admin
- Posts: 3184
- Joined:
Re: Focus event managerment
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.
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.
- lomoonmoonbird
- Posts: 30
- Joined:
Re: Focus event managerment
Hi
pic 1:
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:
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:
this is my Monobehaviour class:
you can try this codes,Thanks
pic 1:
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:
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:
Code: Select all
<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>
Code: Select all
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 () {
}
}
-
sfernandez
Site Admin
- Posts: 3184
- Joined:
Re: Focus event managerment
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.
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.
- lomoonmoonbird
- Posts: 30
- Joined:
Re: Focus event managerment
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
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
- Attachments
-
- putaogame.zip
- this is the demo file
- (254.45 KiB) Downloaded 264 times
-
sfernandez
Site Admin
- Posts: 3184
- Joined:
Re: Focus event managerment
Here is some code to handle the focus yourself:
Code: Select all
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;
}
}
}
Who is online
Users browsing this forum: dstewart and 9 guests