How to move focus from textbox to textbox int contentcontrol in wpf? - wpf

I want to move focus from Title Textbox to Textbox in ContentControl in WPF.
But any command doesn't work.
How can I move focus?
<TextBox
Grid.Row="0"
MinWidth="200"
Name="Title"
VerticalContentAlignment="Center"
mahApps:TextBoxHelper.ClearTextButton="True"
mahApps:TextBoxHelper.Watermark="Task Title"
Text="{Binding Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<StackPanel
Grid.Row="1"
Margin="0,5,0,5"
Background="White">
<ContentControl
MinHeight="55"
Margin="5"
Content="{Binding CreateTaskControl}" />
</StackPanel>

you can use Focusable="True" and KeyboardNavigation.TabIndex="1"
And of course if TabIndex you did not use it.
this code Focusable="True" and KeyboardNavigation.TabIndex="1" Useful for places that do not accept the TabIndex element, such as TextBlock

Related

WPF set Grid row tooltip

I have a Grid in which I have a RichTextBox control for the description text and there is a ToolTip attached with that RichTextBox. Please check the below code-
<Grid Grid.Row="1" >
<controls:RichTextBox Text="{Binding Description, Mode=TwoWay}"
VerticalAlignment="Stretch" VerticalContentAlignment="Stretch" IsEnabled="False" />
<Grid.ToolTip>
<ToolTip>
<TextBlock Text="{Binding Path=Descriptiontext}"
TextTrimming="CharacterEllipsis" TextWrapping="Wrap" />
</ToolTip>
</Grid.ToolTip>
</Grid>
And I wanted to set "ToolTipService.ShowDuration" property for ToolTip. But I am not getting a way, where to attach it.
Can anyone suggest how we can do that.
The ShowDuration property is actually an attached property from the contained TooltipService. You can put it either on the ToolTip itself or the parent Grid. i.e.
<Grid Grid.Row="1" ToolTipService.ShowDuration="5000">
<controls:RichTextBox Text="{Binding Description, Mode=TwoWay}"
VerticalAlignment="Stretch" VerticalContentAlignment="Stretch" IsEnabled="False" />
<Grid.ToolTip>
<ToolTip>
<TextBlock Text="{Binding Path=Descriptiontext}"
TextTrimming="CharacterEllipsis" TextWrapping="Wrap" />
</ToolTip>
</Grid.ToolTip>
</Grid>

Overriding parent control's datacontext with local datacontext

I have a Groupbox in which i have multiple Textboxes. All these Textbox derive their Datacontext from that of Groupbox but one of the Textbox in the group needs a different Datacontext.
<GroupBox Header="My Group" Height="150" Width="1132" DataContext="{Binding ContextA}" >
<Grid>
<Label x:Name="lblA" Content="Policy Number:" Margin="6,12,970,92" />
<TextBox x:Name="txtbA" Margin="155,12,0,0" HorizontalAlignment="Left" Height="24" TextWrapping="Wrap" Text="{Binding ValueA}" VerticalAlignment="Top" Width="278" Grid.ColumnSpan="2"/>
<Label x:Name="lblB" Content="Policy Type:" Margin="612,10,334,88" Height="30"/>
<TextBox x:Name="txtbB" Margin="801,12,0,0" HorizontalAlignment="Left" Height="24" TextWrapping="Wrap" DataContext="{Binding ContextB}" Text="{Binding ValueB}" VerticalAlignment="Top" Width="278"/>
</Grid>
</GroupBox>
In the above code txtbA uses the Datacontext same as that of Groupbox.
I want txtbB to have a separate Datacontexti.e. ContextB
But the ContextB is not getting assigned to txtbB. How to solve the problem?
Note:
ContextAand ContextB= list of Entity Framework models.
WPF binding engine look for property in current DataContext. So, in your case binding engine is looking for property ContextB in class ContextA since textBox is inheriting DataContext from parent GroupBox.
What you can do is use more verbose definition for ContextA like this:
<GroupBox Header="My Group" Height="150" Width="1132"
DataContext="{Binding}"> <-- HERE Or can remove setting DC altogether.
<Grid>
<Label x:Name="lblA" Content="Policy Number:" Margin="6,12,970,92" />
<TextBox x:Name="txtbA" Margin="155,12,0,0" HorizontalAlignment="Left"
Height="24" TextWrapping="Wrap"
Text="{Binding ContextA.ValueA}" <-- HERE
VerticalAlignment="Top"
Width="278" Grid.ColumnSpan="2"/>
<Label x:Name="lblB" Content="Policy Type:" Margin="612,10,334,88"
Height="30"/>
<TextBox x:Name="txtbB" Margin="801,12,0,0" HorizontalAlignment="Left"
Height="24"
TextWrapping="Wrap" DataContext="{Binding ContextB}"
Text="{Binding ValueB}" VerticalAlignment="Top" Width="278"/>
</Grid>
</GroupBox>

How do I Raise an Event when the Binding is completed?

I have a TextBox in my application that i am developing and the binding is done in the xaml
I want to be able to raise an event when the binding of the TextBox Text Property is completed meaning when the text is loaded/changed through binding into the TextBox how do i achive this?
I tried TextChanged Event also Loaded Event but no luck right after the Binding is complected so how do i do it?
<ListBox x:Name="listBoxCategories" Background="Transparent" BorderThickness="0" Grid.Row="4" Grid.ColumnSpan="2" Margin="0" Padding="0" ItemContainerStyle="{StaticResource ListBoxItemStyle}" ItemsSource="{Binding ElementName=discussion_categoryDomainDataSource, Path=Data}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="stackPanelCategory" Orientation="Vertical" Margin="0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<TextBlock x:Name="TextBlockCategoryId" Text="{Binding Path=CategoryID}" />
<toolkit:Expander IsExpanded="True" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Style="{StaticResource ForumExpanderStyleRight}">
<toolkit:Expander.Header>
<TextBlock FontSize="16" FontWeight="Bold" Foreground="White" Margin="4,0,4,0" Text="{Binding CategoryName}" LayoutUpdated="TextBlock_LayoutUpdated" />
</toolkit:Expander.Header>
<ListBox x:Name="listBoxBoards" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Background="Transparent" BorderThickness="0" Margin="0" Padding="0" ItemContainerStyle="{StaticResource ListBoxItemStyle}" ItemsSource="{Binding CategoryBoards}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="0" HorizontalAlignment="Stretch" x:Name="GridBoard">
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</toolkit:Expander>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
at this line
<TextBlock x:Name="TextBlockCategoryId" Text="{Binding Path=CategoryID}" />
I want an event where when the Binding is completed i want to give a different data source for the list box under the parent stack panel so i need the binding event so when i have the catedory id int he text block which later will be hidden in the xaml ( which now is not collapsed for testing reasons )
This is a slightly peculiar thing to want to do, it might help if you tell us why you are wanting to do this?
However, with no other information to hand, I will propose a solution.
If the TextBox API events do not provide the infomation you need, try handing the LayoutUpdated event. This event fires each time layout occurs, which is typically as elements ae added to the visual tree. WHen this event fires inspect your TextBox.Text property to see if it is set.
This solved the problem for me :)
<TextBlock FontSize="16" FontWeight="Bold" Foreground="White" Margin="4,0,4,0" Text="{Binding CategoryName}" Loaded="TextBlock_Loaded" />
Loaded event in the inner Text block rather than the upper textblock because by the time this is loaded the upper text block's text is already bound so i can retrive the ID :)

WPF - How to stop TextBox from autosizing?

I have a textbox in my visual tree as follows..
Window
Grid
ListBox
ItemTemplate
DataTemplate
Grid
Grid
Textbox...
The textbox is defined as..
<TextBox Height="Auto"
Text="{Binding Path=LyricsForDisplay}"
MinHeight="50"
MaxHeight="400"
Visibility="Visible"
VerticalScrollBarVisibility="Auto"
IsReadOnly="True"
AllowDrop="False"
TextWrapping="WrapWithOverflow">
</TextBox>
When long text is added to the bound variable (LyricsForDisplay) all of the items in the listbox expand their textboxes/grids width's to allow for the entire string to be seen if you use the scrollbar on bottom that appears...
What I would like to do is make it so the boxes/grids only resize if the user stretches the window .. NOT when a long text is entered (it could just wrap around..)
Does anyone know how to obtain the functionality?
The following works:
<ListBox Name="ListBox1"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid>
<TextBox TextWrapping="Wrap"></TextBox>
</Grid>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Notice the use of ScrollViewer.HorizontalScrollBarVisibility="Disabled" and TextWrapping="Wrap".
Unfortunately, the regular TextBox doesn't allow autoresize to fit the parent but NOT autoresize when the text doesn't fit.
To solve this problem, you can use a custom TextBox that reports a desired (0, 0) size. It's an ugly hack, but it works.
In your .xaml.cs file:
public class TextBoxThatDoesntResizeWithText : TextBox
{
protected override Size MeasureOverride(Size constraint)
{
return new Size(0, 0);
}
}
Then, in your .xaml file:
<Window x:Class="YourNamespace.YourWindow"
...
xmlns:local="clr-namespace:YourNamespace">
...
<local:TextBoxThatDoesntResizeWithText Height="Auto"
Text="{Binding Path=LyricsForDisplay}"
MinHeight="50"
MaxHeight="400"
Visibility="Visible"
VerticalScrollBarVisibility="Auto"
IsReadOnly="True"
AllowDrop="False"
TextWrapping="WrapWithOverflow">
</local:TextBoxThatDoesntResizeWithText>
...
</Window>
Something needs to contrain the horizontal width available to the TextBoxes, in this case you want to stop the ListBox from growing horizontally indefinitely:
<ListBox HorizontalScrollBarVisibility="Disabled"
two change the code:
1- add border tag with your grid.column and grid.row size that you are neads.
2- width and height of textbox set to it.
sample:
<Border x:Name="b" Margin="5"/>
<TextBox Height="Auto"
Text="{Binding Path=LyricsForDisplay}"
MinHeight="50"
Width="{Binding ActualWidth, ElementName=b}"
Height="{Binding ActualHeight, ElementName=b}"
Visibility="Visible"
VerticalScrollBarVisibility="Auto"
IsReadOnly="True"
AllowDrop="False"
TextWrapping="Wrap">
</TextBox>
Try setting the the MaxWidth Property in Your Textbox
<TextBox Height="Auto" Text="{Binding Path=LyricsForDisplay}" MinHeight="50" MaxHeight="400" Visibility="Visible" VerticalScrollBarVisibility="Auto" MaxWidth="100" IsReadOnly="True" AllowDrop="False" TextWrapping="WrapWithOverflow"> </TextBox>

Encapsulating repeated layout in WPF

In a datatemplate that I am binding to a viewmodel I have a grid like so:
<Grid>
.
. <!--Row & Col Definitions...-->
.
<TextBlock Text="Some Label" Style="{DynamicResource TextBlockLabelStyle}" />
<TextBlock Grid.Column="1" Text="{Binding SomeValue, Mode=OneWay}"/>
<Border Style="{DynamicResource SeparatorStyle}" />
<TextBlock Grid.Row="1" Text="Some Label" Style="{DynamicResource TextBlockLabelStyle}" />
<TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding SomeValue, Mode=OneWay}"/>
<Border Grid.Row="1" Style="{DynamicResource SeparatorStyle}" />
<TextBlock Grid.Row="2" Text="Some Label" Style="{DynamicResource TextBlockLabelStyle}" />
<TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding SomeValue, Mode=OneWay}"/>
<Border Grid.Row="2" Style="{DynamicResource SeparatorStyle}" />
</Grid>
I thought that adding this repeated pattern (TextBlock for label, TextBlock for value, horizontal rule) was getting tedious and thought it would be best to encapsulate it into a UserControl something like 'GridRow' e.g.:
<UserControl x:Class="GridRow">
<TextBlock Text="{Binding LabelText}" Style="{DynamicResource TextBlockLabelStyle}" />
<TextBlock Grid.Column="1" Text="{Binding ValueText, Mode=OneWay}"/>
<Border Style="{DynamicResource SeparatorStyle}" />
</UserControl>
Then I could just go something like:
<Grid>
<GridRow LabelText="Some Label" ValueText="{Binding SomeValue}"/>
<GridRow Grid.Row="1" LabelText="Some Label2" ValueText="{Binding SomeValue2}"/>
<GridRow Grid.Row="2" LabelText="Some Label3" ValueText="{Binding SomeValue3}"/>
</Grid>
and have the user control bind to LabelText and ValueText properties, perhaps through template binding?
My question is how to do this, and if this is the right way of doing it, or if it is possible to use Styles or datatemplates to do this?
Unfortunately this is something that is not easy to achieve. A Grid layout looks at the Grid.Row and Grid.Column properties of its immediate children in order to create the required layout. Therefore, nesting your UI controls in another Grid will break the layout.
A few options, this blog post fixes the problem, but is complex:
http://www.scottlogic.co.uk/blog/colin/2010/11/using-a-grid-as-the-panel-for-an-itemscontrol/
There is a nice Auto-grid here, I have not used it, but it looks pretty good:
http://whydoidoit.com/2010/10/06/automatic-grid-layout-for-silverlight/
Regards,
Colin E.

Resources