Managing keyboard focus with custom TextBox control template - c#

Currently I'm working on a WPF project which has defined a custom style for TextBox. Among other things, we override the default control template for the TextBox. The control template looks like this (I've removed a lot of the TemplateBinding stuff since it's not relevant).
<Border>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ScrollViewer x:Name="PART_ContentHost"
IsTabStop="False"
Background="{x:Null}"
VerticalAlignment="Center"
BorderThickness="0"/>
<ContentPresenter Grid.Column="1" Margin="5,0,0,0" Focusable="False"
Content="{TemplateBinding local:UnitConversion.Info}"
ContentTemplateSelector="{DynamicResource SelectorKey}"/>
</Grid>
</Border>
Essentially this just adds a ContentPresenter to display a combo box allowing the user to select different units to be used for display or entry into the text box. The template selector simply selects between the user control (which is really just a ComboBox) or an empty template if the text box doesn't have any associated unit data (the content is null).
The Problem
Since this combo box is essentially part of the text box control template, interacting with the combo box gives keyboard focus to the text box without actually placing the caret into the visual text box. Elsewhere we have a keyboard control which is ultimately made visible when a text box gets keyboard focus (the keyboard itself is actually listening for custom routed events, but these are ultimately raised when a TextBox gets focus.
The Question
Is there any way I can prevent the text box from getting focus when anything other than the actual text entry is what technically got focus? My desired behavior is that manipulating the combo box doesn't result in the on-screen keyboard popping up.
My gut instinct here tells me that I can't actually do what I want since all the focus logic happens at the TextBox level and it doesn't really care much about the contents of the control template. But I'm just curious if anyone might be able to think of some kind of workaround.
I'd like to avoid introducing a custom text box control to handle this since we don't much like the idea of application-specific custom controls (especially considering how far we've gotten with the current one).

Related

Let user resize control (textbox, specifically) in Canvas UWP

I have a canvas with a button that the user can press to add a new textbox to the canvas. How can I make it so the user can resize the text box by clicking and dragging on any of the corners of the textbox. Because the textbox is created in the C# code (not XAML), I would prefer code in C# not XAML.
Thanks
EDIT: My question is different than the one referenced because it is in UWP not WPF. These have very different controls. I would appreciate if you could translate the UWP information into UWP C#
You can use Thumb control instead of a textbox. The thumb control provides the functionality for you to write code to customize the drag and drop behavior. A simple code would be:
<Canvas x:Name="test">
<Thumb Width="100" Height="100">
<Thumb.Template>
<ControlTemplate>
<TextBlock HorizontalAlignment="Center" Text="12345"/>
</ControlTemplate>
</Thumb.Template>
</Thumb>
</Canvas>
A more complex sample could be found from this SO thread from Jay's answer. But please notice you need to customize the logic yourself in order to make it resize like what you need. The reference is just a direction.

Do I need dependency properties for all basic properties on my user control?

I am currently writing my first user control which would consist of a label and a text box in a stack panel like follows:
<Grid>
<StackPanel Orientation="Horizontal" DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Label Content="{Binding Label}" Width="60"></Label>
<TextBox Text="{Binding TextBoxContent}" Width="60"/>
</StackPanel>
</Grid>
This will be most useful to be in a settings page, as it will be reused for several different settings. With each of these settings, I will want to set (at a minimum) the width, height, validation rule and error template properties. As for the text itself, I have already created a dependency property both for the label and the text box (as you can see in my snippet above).
My question is this: Do I need to create a dependency property for all of the properties I just mentioned that I would like to set when I actually use my user control? This seems like redundant work (since they already exist on the text box, basically they would just redirect my user control's property to the text box's property of the same name)? This is even more work if I want to use even more properties on my text box (for example, AcceptsReturn, etc).
The redundant work can be saved if you decide to derive from TextBox rather than UserControl - just think of your control as a "labeled textbox" and all you need to do is derive from TextBox and add the needed dependency properties to accommodate for the label. This of course would not be the case for more complex user controls, but it seems OK in your case.
The downside to this though is that you'll have to take the default control template for TextBox and work with it to add your label, which may be a bit trickier.
Either way, I recommend having a look at the Control Authoring Overview page on MSDN, which is extremely useful when writing your first controls in WPF.

Create a popup on templated content not using a ToolTip [WPF]

Introduction
For a project I am working on I had to create a ContentControl which must display a ToolTip/Popup when some provided content is not allowed.
For example:
A TextBox is wrapped inside my ContentControl, the ContentControl provides the logic of displaying a ToolTip when unwanted characters are being typed in the TextBox.
A ToolTip would appear displaying the unwanted characters and after x-period of time, the ToolTip would dissapear.
However using the ToolTip approach led to unexpected and unwanted behavior;
on mouse over an empty tooltip is shown (we could get this to close immediately, but it was still visible for a moment)
when the mouse left the control, the tooltip was hidden
the slide effect could not be controlled precise enough, so depending on the location of the tooltip (above or below) the effect was correct or not.
Therefore I need to have another solution which does not rely on the ToolTip.
Example code
The Xaml structure is like
<ContentControl x:Class="xxx.yyy.zzz.UserControls.MyContentControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
... more namespaces ...>
<ContentControl.Template>
<ControlTemplate TargetType="ContentControl">
<ContentPresenter Content="{TemplateBinding Content}">
<ContentPresenter.ToolTip>
...
And it's usage is like:
<UserControl:Class="xxx.yyy.UserControls.TextBoxControl"
xmlns:cn="clr-namespace:xxx.yyy.zzz.UserControls">
<cn:MyContentControl Info="{Binding ..}" x:Name="MyContentControlName">
<TextBox Text="{Binding Text}" .."/>
</cn:MyContentControl>
Where Info is a dependency property used by my ContentControl's codebehind and for which the input binding is provided by the TextBoxControl's ViewModel.
On a side note:
For our validations we rely on Validation Error Style in WPF, similar to Silverlight and an implementation of How can I move a WPF Popup when its anchor element moves?
I have tried to incorporate some of the template code from the first link mentioned and that resulted only in display a minuscule popup, not displaying anything and neither giving me the behavior I was expecting.
As can be seen in the code snippet, formerly I was using ContentPresenter.ToolTip, unfortunately there is no such thing a ContentPresenter.Popup, whereas I believe a ToolTip is a popup
The question
So how would it be possible to create popup like behavior especially for this piece of code? (this will represent the TextBox on the WPF UI)
<ContentPresenter Content="{TemplateBinding Content}">

Most simple FrameworkElement to handle HorizontalAlignment and VerticalAlignment?

This is Silverlight.
Initial goal is to display a random element in a Popup with some VerticalAlignment and HorizontalAlignment. I do not want to use VerticalOffset or HorizontalOffset, because there is more to what I really want to do, including some complex bindings.
First attempt was:
<Popup>
<Button
Height="135"
HorizontalAlignment="Stretch"
VerticalAlignment="Bottom" />
</Popup>
Second attempt was:
<Popup
Height="135"
HorizontalAlignment="Stretch"
VerticalAlignment="Bottom">
<Button />
</Popup>
Both were a failure: the Button was always on Top and not Stretch (HorizontalAlignment and VerticalAlignment didn't work).
So I had the idea to encapsulate the element in a simple FrameworkElement:
<Popup>
<Border>
<Button
Height="135"
HorizontalAlignment="Stretch"
VerticalAlignment="Bottom" />
</Border>
</Popup>
And it is working.
But I had to use Border in this example, when I could have done it with Grid and many other FrameworkElement (but not with Canvas or Viewbox or Popup). I'd like to know what is the most simple, efficient and processor-friendly transparent FrameworkElement to encapsulate another element with working HorizontalAlignment and VerticalAlignment? Is it:
Border? (like the above example)
UserControl?
ContentControl?
ContentContainer?
some custom and basic MyFrameworkElement? (might need help for most basic implementation)
something else like Grid?
WPF controls come in two flavors: Ones that interact with users (like accept user clicks like a button, or display text like a text block) and containers that control placement and layout of the previous ones.
Container controls are usually designed to lay out their children in a specific manner. For example, Canvases lay out children by X, Y, Width & Height values. Each one has a specific use, so you must read the documentation or tutorials for these container controls and understand how each works in order to select the appropriate one for a task.
In your case, you want the button to fill all available space in the popup (it seems, it isn't that clear). I know that the Grid does this by default. So I would do the following:
<Popup><Grid><Button /></Grid></Popup>

How to hide part of text in a richtextbox or textbox using WPF?

i would like to ask for a a way in wpf of hiding and unhiding some specific lines in a richtextbox or textbox using C# at Runtime and at the same time leave the rest of the lines visible. I would also like not to be a visible space between the visible and unvisible lines. i have an idea of selecting the lines and then change font size to 0.01, but it isnt so much elegand.
thanks in advance.
By default, you can only hide and show certain text in a WPF TextBox or RichTextBox by changing the value of the Text or RichText properties respectively. For example if you have the text "Mary had a little lamb who's fleece was white as snow" and wanted to hide the text "who's fleece was white as snow" conditonaly you would have to parse the text and remove or add "who's fleece was white as snow" in the correct location in the Text or RichText using code.
It sounds like you are just trying to modify the layout depending on certain conditions though. In that case, it is better to split the lines up into separate TextBoxes and set the visibility of those textboxes to Collapsed when certain conditions exist and set them to Visible otherwise.
If you are using TextBox you will want an outer Border which will help you match the style of TextBox, then you can set the BorderBrush and Background of the textboxes you are hiding to Transparent so it just looks like a single TextBox.
<Border
BorderThickness="1"
BorderBrush="Black"
Background="White">
<StackPanel>
<TextBox
Text="Mary had a little lamb "
BorderBrush="Transparent"
Background="Transparent" />
<!-- Set the Visisibility Property of this TextBox in code to show or hide it -->
<TextBox
Name="ConditionalTextBoxLine"
Visibility="Visible"
Text="Who's fleece was white as snow"
BorderBrush="Transparent"
Background="Transparent" />
</StackPanel>
</Border>

Categories

Resources