Focus movement between list and other elements. WPF - wpf

In my window I have the listview and other elements. How I can achieve such behavior of focus: when I press downkey on last listitem focus moves from listview on another element, accordingly pressing upkey on first element moves focus away from list.
So focus on pressing up-downkeys can move from other elements to the list, pass throw the list and leave from the list.
Thanks in advance.

Set the KeyboardNavigation.DirectionalNavigation attached property to Continue. The default for ListBox is Contained.
<ListBox KeyboardNavigation.DirectionalNavigation="Continue"/>

I have different situations in my application. For all controls I have my styles, but in style for the tabcontrol I set property KeyboardNavigation.DirectionalNavigation="Continue".
1. Here should have possibility to be selected listviewitems and tabitems. And when focus on tabitem and I press (->) tabitem changes.
2. Here should have possibility to be selected listboxitems and buttons.
3. Here should have possibility to be selected TabItem and TextBlocks.
And I can use just arrows not tab. 1:
<TabControl Name="tabControl1">
<TabItem Header="PORT" Name="PORT">
<ListView x:Name="ATList"
ItemsSource="{Binding Path=., NotifyOnTargetUpdated=true}"
KeyboardNavigation.DirectionalNavigation="Continue"
KeyUp="ATList_KeyUp" TargetUpdated="ATList_TargetUpdated">
<ListView.View>
<GridView >
<GridViewColumn> ........
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</TabItem>
.......
</TabControl>
2.
<Grid>
<ListBox ItemsSource="{Binding NotifyOnSourceUpdated=True, NotifyOnTargetUpdated=True}"
KeyboardNavigation.DirectionalNavigation="Continue"
ClipToBounds="true" TargetUpdated="List_TargetUpdated" SourceUpdated="List_SourceUpdated">
</ListBox>
<WrapPanel>
<Label .../>
<Label .../>
<Button x:Name="NewBtn"
IsEnabled="{Binding ElementName=UsedMemory, Path = Content, Converter={StaticResource RouteNewConverter}}"
Click="NewRouteBtn_Click"> New </Button>
<Button x:Name="DeleteBtn" Click="DeleteBtn_Click"> Delete </Button>
</WrapPanel>
</Grid>
3.
<TabControl Margin="2,5,2,1" Name="tabControl1" >
<TabItem Header="AV" Name="AV">
<Grid>
<StackPanel x:Name="inf">
<TextBlock />
...
<TextBlock />
</StackPanel>
</Grid>
</TabItem>
</TabControl>

Related

stop Text block (not Text box) from tabbing sequence

How to exclude TextBlock from tabbing sequence in SILVERLIGHT Grid XAML. I know for TextBox, we use IsTabStop false OR TabIndex -1, but same property is not avaiable for TextBlock
I have 4 controls, 1 and 4 are TextBox (editable) and 2 and 3 are TextBlock (non editable). When I tab, all the 4 are included in the tabbing sequence.
I want to exclude 2,3 (Textblocks) from tabbing. Means, If I tab from TextBox 1, focus should move directly to TextBox 4. please help.
Loaded="UserControl_Loaded">
<DataTemplate x:Key="CellEditClientAllocations" >
<TextBox Text="{Binding ClientAllocations, Mode=TwoWay}"
Style="{StaticResource GridCellTextBoxStyle}"
x:Name="tbxClientAllocations"
Loaded="TextBox_Loaded"
TextChanged="tbxClientAllocations_TextChanged"
KeyDown="tbxClientAllocations_KeyDown"
LostFocus="tbxClientAllocations_LostFocus"
GotFocus="tbxClientAllocations_GotFocus"/>
</DataTemplate>
<DataTemplate x:Key="CellAccountId">
<TextBlock Text="{Binding AccountId, Converter={StaticResource anc}}" Style="{StaticResource GridCellTextBlockStyle}" /> </DataTemplate>
<DataTemplate x:Key="CellEditAccountId">
<TextBox Text="{Binding AccountId, Converter={StaticResource anc}, Mode=TwoWay}" x:Name="tbxAccountId" LostFocus="TbxAccountIdLostFocus" TextChanged="TbxAccountIdTextChanged" GotFocus="tbxAccountId_GotFocus"/>
</DataTemplate><DataTemplate x:Key="CellAccountName"> <StackPanel>
<TextBlock VerticalAlignment="Center" Text="{Binding AccountName, Mode=TwoWay}" Foreground="{Binding IsAccountValid, Converter={StaticResource cc}}" kStyle="{StaticResource GridCellTextBlockStyle}" Name="Account" MouseRightButtonUp="" > </TextBlock> </StackPanel> </DataTemplate>
<DataTemplate x:Key="CellLotInstructions"> <StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding LotInstructions}" Style="{StaticResource GridCellTextBlockStyle}"/>
<HyperlinkButton Content="Edit" Style="{StaticResource HyperlinkButtonStyleUnderline}" IsEnabled="{Binding LotInstructionsEnabled}" Name="Lotinstructons" HorizontalContentAlignment="Center" MouseLeftButtonDown="LotinstructonsMouseLeftButtonDown" VerticalContentAlignment="Center" Click="ViewSpecifyLots_Click" Visibility="{Binding LotInstructionsEdit}" /> </StackPanel> </DataTemplate>
Try setting attached property KeyboardNavigation.TabNavigation to None.
<TextBlock KeyboardNavigation.TabNavigation="None"/>
Set Focusable="False" for the textblock
I think you may need to work on the DataGrid Column rather than the Cell content (your TextBlock) it is the Cell that is Focussed not the TextBlock.
You could assign an event handler to the CellEnter Event (accessible from the definition of the original column) and then set the DataGrids selected cell selected property to false. Not the neatest solution but it should work.
Alternatively you could create a behaviour to do this....
Hope this helps!

Make TabItem select first nested button when clicked (WPF MVVM)

As the title says, I would like the first nested Button to be selected (this button selects a view) when the tab item is clicked. Here is my code below:
<TabItem Header="Scheduling">
<StackPanel Style="{StaticResource ResourceKey=TabStackPanelStyle}">
<RadioButton Command="{Binding BookResourceCommand}" Style="{StaticResource ResourceKey=TabButtonStyle}">Book</RadioButton>
<RadioButton Command="{Binding NewResourceCommand}" Style="{StaticResource ResourceKey=TabButtonStyle}">New</RadioButton>
<RadioButton Command="{Binding EditResourceCommand}" Style="{StaticResource ResourceKey=TabButtonStyle}">Edit</RadioButton>
<RadioButton Command="{Binding DeleteResourceCommand}" Style="{StaticResource ResourceKey=TabButtonStyle}">Delete</RadioButton>
</StackPanel>
</TabItem>
This TabItem sits in a TabControl with a few more similar TabItems. All I want to do is have the TabItem select the first RadioButton (by default) when it is clicked. These radio buttons change a user control in my ViewModel.
I know it would be possible using EventTriggers associated with the TabItem but there must be a better way.
Thanks!
I think in this situation you can use Binding:
TabItem
<TabItem x:Name="MyTabItem" Header="Two">
<Label Content="Some Content" />
</TabItem>
RadioButton
<RadioButton Name="MyButton" Content="Two" IsChecked="{Binding ElementName=MyTabItem, Path=IsSelected}" />
If you want to be when you click on the RadioButton, the tab is not selected, use Mode=OneWay:
<RadioButton Name="MyButton" IsChecked="{Binding ElementName=MyTabItem, Path=IsSelected, Mode=OneWay}" />

TabControl with an new tab button

I have the following TabControl:
<TabControl x:Name="Networks">
<TabControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding DisplayName}" />
<Button Content="X" cal:Message.Attach="CloseItem($dataContext)" />
</StackPanel>
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
As you can see it is bound to a ViewModel using Caliburn.Micro, but I think this is unrelevant.
How would I add a button on to this control on the right side to add new TabItems? I'm looking for simple solution. I've searched for this but I haven't found an easy implementation of this.
Thanks
You could make the ItemsSource a CompositeCollection with a CollectionContainer for the tabs at the beginning and one explicit TabItem at the end which can add a new item on click (a +-tab as in some browsers).

Pattern for working with a form in Silverlight 4? (How to get references to XAML elements)

I have a form:
<StackPanel Orientation="Horizontal" Visibility="{Binding Editable, Converter={StaticResource visibilityConverter}}"
ToolTipService.ToolTip="Add new topic to this group">
<sdk:AutoCompleteBox Width="160" ItemsSource="{Binding ElementName=LayoutRoot, Path=DataContext.TopicNames}" />
<Button Click="addTopicButton_Click">
<Image Source="Images/appbar.add.rest.png" />
</Button>
</StackPanel>
This form appears in a DataTemplate for an ItemsControl. I'm not sure what the best way is to get the data from the AutoCompleteBox when the button is clicked. I can't give the elements x:Name attributes, because they're in a template (right?).
How can I get around this? The Click event will give me the Button, but I need a reference to the text box. Use the Button's parent, then look through the children for the Textbox? If I factored this out into its own UserControl, I could set x:Name values, but I'd rather not do that.
Any other ideas?
Update: Here is another example of such a problem:
<ListBox x:Name="topicList"
ItemsSource="{Binding Id, Converter={StaticResource topicGroupIDConverter}}"
SelectionChanged="ListBox_SelectionChanged"
HorizontalAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}"
Width="150"
VerticalAlignment="Center"
ToolTipService.ToolTip="{Binding Description}"
ToolTipService.Placement="Right" />
<Button ToolTipService.ToolTip="Remove this topic from this group"
Visibility="{Binding ElementName=topicList,
Path=DataContext.Editable,
Converter={StaticResource visibilityConverter}}"
Click="removeTopicButton_Click"
HorizontalAlignment="Right"
Margin="10,0">
<Image Source="Images/appbar.cancel.rest.png" />
</Button>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
When the button is clicked, I want to access topicList.DataContext. However, topicList itself is a DataTemplate in an ItemsControl, so I can't access it using its name from code-behind. How else can I do this?
You can add a property, say SelectedItemInAutoCompleteBox, to your presenter, and then can bind it to the SelectedItem property of AutoCompleteBox, using Mode=TwoWay, like this,
<sdk:AutoCompleteBox SelectedItem="{Binding Path=DataContext.SelectedItemInAutoCompleteBox, Mode=TwoWay}" ... />
You may try the same approach with Text property of AutoCompleteBox, also. See if it solves your problem.:-)
You have several choices:
If you're on Silverlight 5, use the AncestorBinding
Otherwise, use a Silverlight 4 AncestorBinding hack (it doesn't look pretty)
Or you could try DataContextProxy, which stores the DataContext in a resource so that it is accessible. Note: you should set the DataContextProxy as a Resource of topicList ListBox, not the UserControl as in Dan Wahlin's example.

WPF ListBoxItem selection problem

I have a listbox where the items contain checkboxes:
<ListBox Style="{StaticResource CheckBoxListStyle}" Name="EditListBox">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Click="Checkbox_Click" IsChecked="{Binding Path=IsChecked, Mode=TwoWay}" Content="{Binding Path=DisplayText}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The problem I'm having is that when I click on the checkbox or its content, the parent ListBoxItem does not get selected. If I click on the white space next to the checkbox, the ListBoxItem does get selected.
The behavior that I'm trying to get is to be able to select one or many items in the list and use the spacebar to toggle the checkboxes on and off.
Some more info:
private void Checkbox_Click(object sender, RoutedEventArgs e)
{
CheckBox chkBox = e.OriginalSource as CheckBox;
}
In the code above when I click on a checkbox, e.Handled is false and chkBox.Parent is null.
Kent's answer put me down the right path, here's what I ended up with:
<ListBox Style="{StaticResource CheckBoxListStyle}" Name="EditListBox" PreviewKeyDown="ListBox_PreviewKeyDown">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding Path=IsChecked, Mode=TwoWay}" />
<TextBlock Text="{Binding DisplayText}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I had to use PreviewKeyDown because by default when you hit the spacebar in a list box, it deselects everything except for the most recently selected item.
To begin with, put the content outside the CheckBox:
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsChecked}"/>
<TextBlock Text="{Binding DisplayText}"/>
</StackPanel>
After that, you will need to ensure that pressing space on a ListBoxItem results in the CheckBox being checked. There are a number of ways of doing this, including a simple event handler on the ListBoxItem. Or you could specify a handler for UIElement.KeyUp or whatever in your DataTemplate:
<CheckBox IsChecked="{Binding IsChecked}" UIElement.KeyUp="..."/>
You can also bind the IsChecked property of the CheckBox and IsSelected property of the ListBoxItem:
<ListBox>
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding DisplayText}" IsChecked="{Binding Path=IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
In your use case it would be way simpler to use a ItemsControl instead of a list box. A ItemsControl is similar to a Listbox except that it doesn't contain the automatic selection behaviour. Which means that using it to host a list of what are essentially checkboxes is very simple and you don't have to workaround the ListBox's selection behaviour.
Simply switching to ItemsControl will give you exactly what you need:
<ItemsControl Style="{StaticResource CheckBoxListStyle}" Name="EditListBox">
<ItemsControl .ItemTemplate>
<DataTemplate>
<CheckBox Click="Checkbox_Click" IsChecked="{Binding Path=IsChecked, Mode=TwoWay}" Content="{Binding Path=DisplayText}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
You can click on text to check checkboxes (default behavior) and you can use the keyboard too without having to wire up any event handlers.

Resources