Setting Focus Does Not Allow Instant Editing - wpf

I have a WPF UserControl with a textbox. Here's how the textbox and it's parent control are defined:
<DockPanel Margin="10,20,10,10" FocusManager.FocusedElement="{Binding ElementName=uxJobNumber}" >
<TextBox x:Name="uxJobNumber" Text="{Binding JobNumber, Mode=TwoWay, ValidatesOnDataErrors=True}" TextWrapping="Wrap" FontSize="48" BorderBrush="Black" BorderThickness="1" Margin="10"/>
</DockPanel>
With the FocusManager.FocusedElement set, I can see a cursor bar present within the textbox. However, the cursor bar is not blinking, and does not allow the user to immediately start typing.
Without the FocusManager.FocusedElement set, when the application starts there is no cursor bar within the text box at all.
Here's the complete XAML
<UserControl x:Class=""
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:converters="clr-namespace:.Modules.Converters"
xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit/extended"
xmlns:extToolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit/extended"
mc:Ignorable="d">
<UserControl.Resources>
<converters:VisibilityConverter x:Key="Visibility" />
</UserControl.Resources>
<Canvas Width="1024" Height="768" >
<Border Style="{DynamicResource GroupBox}" Canvas.Left="36.261" Canvas.Top="32.131" Width="426.936">
<StackPanel>
<Border>
<TextBlock Text="STEP 1"/>
</Border>
<TextBlock Text="Enter the five (5) digit Job Number and click Verify." />
<Path/>
<DockPanel Margin="10,20,10,10" FocusManager.FocusedElement="{Binding ElementName=uxJobNumber}" >
<Button Content="Verify" Width="125" Height="65" HorizontalAlignment="Right" Command="{Binding SearchJobCommand}" Style="{DynamicResource RedButton}" Margin="0" DockPanel.Dock="Right" IsDefault="True"/>
<TextBox Text="{Binding JobNumber, Mode=TwoWay, ValidatesOnDataErrors=True}" TextWrapping="Wrap" FontSize="48" BorderBrush="Black" BorderThickness="1" x:Name="uxJobNumber" Margin="10" KeyboardNavigation.TabIndex="0" />
</DockPanel>
</StackPanel>
</Border>
<TextBlock Text="{Binding Error}" Visibility="{Binding HasError, Converter={StaticResource Visibility}}" Canvas.Left="48" Canvas.Top="288" FontSize="16" Width="403" Foreground="Red" />
</Canvas>

We finally resorted to using the Focus() method in the code behind when the form is done loading.
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
uxJobNumber.Focus();
}

Using your code I get this to work; blinking and all.

Related

Binding not working inside the content presenter when its visibility is switched from collapsed state to visible state

When the Visibility of ContentPresenter is set to Collapsed and change its Visibility at runtime, breaking the binding of the element kept inside its content.
XAML
<Grid>
<Button x:Name="button"
Width="100"
Height="20"
Margin="173,23,230,268"
Click="button_Click"
Content="Button" />
<ContentPresenter x:Name="contentPresenter"
Margin="0,62,12,0"
Visibility="Collapsed">
<ContentPresenter.Content>
<StackPanel>
<TextBox x:Name="test2"
Width="200"
Height="20" />
<TextBox Width="200"
Height="20"
Text="{Binding ElementName=test2,
Path=Text,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
</ContentPresenter.Content>
</ContentPresenter>
</Grid>
Code
private void button_Click(object sender, RoutedEventArgs e)
{
if (contentPresenter.IsVisible == false)
{
contentPresenter.Visibility = System.Windows.Visibility.Visible;
}
else if (contentPresenter.IsVisible == true)
{
contentPresenter.Visibility = System.Windows.Visibility.Collapsed;
}
}
Any one help.
if you put your content into a usercontrol your binding will work. if you check your output at runtime you would see that there is a binding error. meaning there is no element with "test2"
<Grid>
<Button x:Name="button"
Width="100"
Height="20"
Margin="173,23,230,268"
Click="button_Click"
Content="Button" />
<ContentPresenter x:Name="contentPresenter"
Margin="0,62,12,0"
Visibility="Collapsed">
<ContentPresenter.Content>
<WpfApplication1:UserControl1/>
</ContentPresenter.Content>
</ContentPresenter>
</Grid>
usercontrol
<UserControl x:Class="WpfApplication1.UserControl1"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<StackPanel>
<TextBox x:Name="test2"
Width="200"
Height="20" />
<TextBox Width="200"
Height="20"
Text="{Binding ElementName=test2,
Path=Text,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
</Grid>
</UserControl>

Stretching of WPF StackPanel

I'm playing around with WPF and I'm trying to create an ImageButton control. I've created a UserControl as follows:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="WpfPractise.Controls.ImageButton"
Height="auto" Width="auto" x:Name="ImageButtonControl">
<Button>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
<Image Source="{Binding Image, ElementName=ImageButtonControl}"
Width="16" Height="16"
Margin="5,0,0,0" VerticalAlignment="Center"/>
<TextBlock Text="{Binding Text, ElementName=ImageButtonControl}"
Margin="5,0,0,0" VerticalAlignment="Center"/>
</StackPanel>
</Button>
This is working fine except for the StackPanel doesn't stretch to fill the width or the height! I've tried a Grid in it's place but to no avail. Any ideas where I'm going wrong?
Example:
If you want to align the Button content to the left then you have to set the HorizontalContentAlignment of the button
<Button HorizontalContentAlignment="Left" VerticalContentAlignment="Center">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
<Image Source="{Binding Image, ElementName=ImageButtonControl}"
Width="16" Height="16"
Margin="5,0,0,0" VerticalAlignment="Center"/>
<TextBlock Text="{Binding Text, ElementName=ImageButtonControl}"
Margin="5,0,0,0" VerticalAlignment="Center"/>
</StackPanel>
</Button>

Creating a scrollable WPF usercontrol

For an application that I am working on I want to create a custom control that has several buttons on it, If there are too many buttons I need it to scroll. However, I don't want to use the standard scrollbar instead I just want to have two buttons at either end of the control one to scroll up and the other down. What is the best way to achieve this?
Is it possible to change the style of the scrollbar so that they are just buttons and not the full horizontal GUI?
You would normally use a ScrollViewer to achieve this. For example:
<UserControl x:Class="WpfApplication2.UserControl1"
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"
mc:Ignorable="d"
d:DesignHeight="200" d:DesignWidth="300">
<ScrollViewer>
<StackPanel>
<Button Content="Test"/>
<Button Content="Test"/>
<Button Content="Test"/>
<Button Content="Test"/>
<Button Content="Test"/>
<Button Content="Test"/>
<Button Content="Test"/>
<Button Content="Test"/>
<Button Content="Test"/>
<Button Content="Test"/>
<Button Content="Test"/>
<Button Content="Test"/>
</StackPanel>
</ScrollViewer>
</UserControl>
Will display a vertical scrollbar automatically when required.
You can change the behaviour by specifying VerticalScrollbarVisibility like this
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ScrollViewer VerticalScrollBarVisibility="Visible">
<ScrollViewer VerticalScrollBarVisibility="Hidden">
<ScrollViewer VerticalScrollBarVisibility="Disabled">
There is of course a HorizontalScrollBarVisibility property as well.
The way to solve a problem like this is to examine the properties and methods of the control.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="*" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Button Grid.Row="0" Width="40" HorizontalAlignment="Left" Content="Up" Click="clickSVup"/>
<ScrollViewer x:Name="svBtn" Grid.Row="1" Width="100" HorizontalAlignment="Left"
VerticalScrollBarVisibility="Hidden" HorizontalScrollBarVisibility="Hidden">
<StackPanel>
<TextBlock Text="Text 01"/>
<TextBlock Text="Text 02"/>
<TextBlock Text="Text 03"/>
<TextBlock Text="Text 04"/>
<TextBlock Text="Text 05"/>
<TextBlock Text="Text 06"/>
<TextBlock Text="Text 07"/>
<TextBlock Text="Text 08"/>
<TextBlock Text="Text 09"/>
<TextBlock Text="Text 10"/>
<TextBlock Text="Text 11"/>
<TextBlock Text="Text 12"/>
<TextBlock Text="Text 13"/>
<TextBlock Text="Text 14"/>
<TextBlock Text="Text 15"/>
<TextBlock Text="Text 16"/>
<TextBlock Text="Text 17"/>
<TextBlock Text="Text 18"/>
<TextBlock Text="Text 19"/>
</StackPanel>
</ScrollViewer>
<Button Grid.Row="2" Width="40" HorizontalAlignment="Left" Content="Down" Click="clickSVdn"/>
</Grid>
private void clickSVdn(object sender, RoutedEventArgs e)
{
svBtn.PageDown();
}
private void clickSVup(object sender, RoutedEventArgs e)
{
svBtn.PageUp();
}
I would advise you to use the standard windows scrollbar instead using some custom buttons for scroll up and scroll down. The users are very used to it for scrolling purposes. If you use two buttons you have to further display something else like scrolling progress. Don't reinvent the wheel :)

How to select UI Elements within a custom data template for a listbox item in Silverlight

Hello all I have a usercontrol that I have defined as a data template. What I trying to do is have the results returned in a wrap panel and have each result returned in a tile format. I have this all working and the resutls are returned properly. However I have within the data template items that I would like the user to click upon. (scrollviewer to scroll data, buttons to click and text to select)/ Currently when you click on the selected item the item is selected but it is as if everything inside the listbox item is locked ( not selectable).
I'd appreciate any suggestions as to what I am missing here. Listed below is my code for the user controls and how I reference the wrap panel from app.xaml
SearchResultTileControl.xaml
<UserControl x:Class="UI.Search.Controls.SearchResultTileControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dts="clr-namespace:UI.Search.Commands"
xmlns:formatter="clr-namespace:UI.Search.Commands"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:qr="clr-namespace:UI.Search.Controls.tiles"
d:DesignHeight="300"
d:DesignWidth="400"
mc:Ignorable="d">
<Grid x:Name="LayoutRoot" >
<ListBox x:Name="ResultListBox"
HorizontalAlignment="Stretch"
Background="{x:Null}"
BorderThickness="0"
HorizontalContentAlignment="Stretch"
ItemsPanel="{StaticResource ResultsItemsControlPanelTemplate}"
ItemContainerStyle="{StaticResource ListBoxItemStyle1}"
ItemsSource="{Binding SearchResults[0].Results}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemTemplate>
<DataTemplate>
<formatter:TypeTemplateSelector Content="{Binding}" HorizontalContentAlignment="Stretch">
<!-- Person Template -->
<formatter:TypeTemplateSelector.PersonTemplate>
<DataTemplate>
<qr:ucTilePerson />
</DataTemplate>
</formatter:TypeTemplateSelector.PersonTemplate>
<!-- Incident Template -->
<formatter:TypeTemplateSelector.IncidentTemplate>
<DataTemplate>
<qr:ucTileIncident />
</DataTemplate>
</formatter:TypeTemplateSelector.IncidentTemplate>
</formatter:TypeTemplateSelector>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
Within the Usercontrol ucTilePerson.xaml I have the template setup as:
<UserControl x:Class="UI.Search.Controls.tiles.ucTilePerson"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:formatter="clr-namespace:UI.Search.Commands"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit"
Width="300"
Height="250"
d:DesignHeight="250"
d:DesignWidth="300"
IsHitTestVisible="False"
mc:Ignorable="d">
<UserControl.Resources>
<formatter:TileHighlightConverter x:Key="FormatConverter" />
</UserControl.Resources>
<Grid x:Name="PersonLayoutRoot">
<Rectangle Style="{StaticResource TileBackground}" />
<ScrollViewer Margin="5" BorderBrush="{x:Null}">
<StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<StackPanel Margin="0,0,0,2" Orientation="Horizontal">
<StackPanel>
<Image Width="48"
Height="48"
Source="/Images/search/person.png" />
<TextBlock Style="{StaticResource TileRelevance}" Text="{Binding Relevance}" />
</StackPanel>
<StackPanel>
<HyperlinkButton Content="{Binding Type}" Style="{StaticResource TypeHyperlinkButton}" />
<TextBox Margin="0,0,0,2"
Style="{StaticResource TileTextBox}"
Text="{Binding Content[AgencyName]}"
TextWrapping="Wrap" />
</StackPanel>
</StackPanel>
<toolkit:WrapPanel Margin="0,0,0,2">
<TextBlock Style="{StaticResource TileLabel}" Text="Name" />
<TextBox Margin="0,0,3,0"
Style="{StaticResource TileTextBox}"
Text="{Binding Content[lastname]}" />
<TextBox Margin="0,0,3,0"
Style="{StaticResource TileTextBox}"
Text="{Binding Content[firstname]}" />
<TextBox Style="{StaticResource TileTextBox}" Text="{Binding Content[middlename]}" />
</toolkit:WrapPanel>
<Border Style="{StaticResource TileBorder}">
<toolkit:WrapPanel Orientation="Horizontal">
<StackPanel Style="{StaticResource TileVerticalStackPanel}">
<TextBlock Style="{StaticResource TileLabel}" Text="Race" />
<TextBox Style="{StaticResource TileTextBox}" Text="{Binding Content[race]}" />
</StackPanel>
<StackPanel Style="{StaticResource TileVerticalStackPanel}">
<TextBlock Style="{StaticResource TileLabel}" Text="Sex" />
<TextBox Style="{StaticResource TileTextBox}" Text="{Binding Content[sex]}" />
</StackPanel>
<StackPanel Style="{StaticResource TileVerticalStackPanel}">
<TextBlock Style="{StaticResource TileLabel}" Text="DOB" />
<TextBox Style="{StaticResource TileTextBox}" Text="{Binding Content[dob]}" />
</StackPanel>
</toolkit:WrapPanel>
</Border>
<Border Style="{StaticResource TileBorder}">
<toolkit:WrapPanel Orientation="Horizontal">
<StackPanel Style="{StaticResource TileVerticalStackPanel}">
<TextBlock Style="{StaticResource TileLabel}" Text="Involvement" />
<TextBox Style="{StaticResource TileTextBox}" Text="{Binding Content[involvementtype]}" />
</StackPanel>
<StackPanel Style="{StaticResource TileVerticalStackPanel}">
<TextBlock Style="{StaticResource TileLabel}" Text="Associated Event" />
<TextBox Style="{StaticResource TileTextBox}" Text="{Binding Content[0].EventAssociation}" />
<HyperlinkButton Content="{Binding Content[0].EventID}" Style="{StaticResource TileResultLink}" />
</StackPanel>
</toolkit:WrapPanel>
</Border>
<Border Style="{StaticResource TileBorder}">
<ContentControl Width="256"
Margin="0,0,6,0"
BorderThickness="0"
Content="{Binding HitContext,
Converter={StaticResource FormatConverter}}"
FontSize="11" />
</Border>
</StackPanel>
</ScrollViewer>
</Grid>
And then I set reference to the wrap panel used in the listboxt ItemsPanel in my app.xaml
<ItemsPanelTemplate x:Key="ResultsItemsControlPanelTemplate">
<toolkit:WrapPanel/>
</ItemsPanelTemplate>
I suspect this is something in the Listbox styles that may be preventing this but I am not positive.
Thanks again for any suggestions,
Cheers
Discovered the issue. Within the usercontrol (ucTilePerson) I had IsHitTestVisible set to false. Since it was set at the user control level all elements inherited this property which is why I was getting the effect of not being able to raise any mouse events on anything.
No idea why I set that there other than it was late in the day.
Cheers

WPF TextBox Focus

I am setting focus on a Textbox like this:
<DockPanel
Margin="0,0,0,0"
LastChildFill="True"
FocusManager.FocusedElement="{Binding ElementName=messengerTextToSend}">
<ListBox
x:Name="messengerLabelParticipants"
DockPanel.Dock="Top" Height="79" Margin="0,1,0,0" Padding="0"
Background="{x:Null}" BorderBrush="{x:Null}" BorderThickness="0"
AllowDrop="True"
ItemsSource="{Binding Path=involvedUsers}" ItemTemplate="{StaticResource chatParticipants}" Tag="{Binding Path=chatSessionID}"
Drop="participantList_Drop" DragEnter="participantList_DragEnter" DragLeave="messengerLabelParticipants_DragLeave">
</ListBox>
<TextBox
x:Name="messengerTextToSend"
Focusable="True"
Margin="10,0,10,10"
DockPanel.Dock="Bottom" Height="100"
Tag="{Binding Path=.}"
KeyUp="messengerTextToSend_KeyUp"
Cursor="IBeam"
Style="{StaticResource messengerTextBoxSendText}"/>
<ScrollViewer
x:Name="messengerScroller"
Template="{DynamicResource ScrollViewerControlTemplate1}"
ScrollChanged="messengerScroller_ScrollChanged" Loaded="messengerScroller_Loaded"
Margin="0,10,0,10">
<ListBox
x:Name="messengerListMessages"
Margin="10,0,0,0" Padding="0"
Background="{x:Null}" BorderBrush="{x:Null}" BorderThickness="0"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding Path=messages}" ItemTemplateSelector="{StaticResource messageTemplateSelector}">
</ListBox>
</ScrollViewer>
</DockPanel>
However, when the page load, although the Textbox visually appears to have focus, the cursor is static and I have to manually either click on the Textbox or tab to it in order to start typing. I'm not sure what I'm doing wrong but I've tried every setting, inclduing setting it in the code to get it working. Any assistance would be greatly appreciated.
Move the FocusManager.FocusedElement command to the Window element.
<Window x:Class="MYClass.Views.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="My Window"
FocusManager.FocusedElement="{Binding ElementName=messengerTextToSend}">
Height="400"
Width="600">
<DockPanel>
</DockPanel>
</Window>
Check out this question for the case of a user control.

Resources