Wpf, AvalonEdit and keyboard navigation problem - wpf

I have an AvalonEdit on my window. When I press key combination Ctrl+Up or Ctrl+Down when inside editor, AvalonEdit loses focus, which is transferred to a different control, as below:
This sometimes happen as well when using Ctrl+Left or Ctrl+Right combinations.
My current XAML definition looks like following:
<ae:TextEditor x:Name="teEditor"
Grid.Row="0"
Grid.Column="0"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
BorderThickness="0"
FontFamily="Consolas"
FontSize="10pt"
TabIndex="0"
WordWrap="{Binding ElementName=Root, Path=Handler.WordWrap}"
ShowLineNumbers="{Binding ElementName=Root, Path=Handler.LineNumbers}"
ContextMenu="{StaticResource EditorContextMenu}"
GotFocus="HandleEditorGotFocus"
KeyboardNavigation.ControlTabNavigation="None"
KeyboardNavigation.AcceptsReturn="True"
KeyboardNavigation.DirectionalNavigation="None"
KeyboardNavigation.TabNavigation="None"/>
How can I prevent that?

It turns out, that problem appears, when you place AvalonEdit inside TabControl. In such case you have to disable keyboard navigation on the TabControl by adding:
KeyboardNavigation.TabNavigation="Local" KeyboardNavigation.DirectionalNavigation="Contained"

Related

WPF TextBox in DataTemplate of ToggleButton does not show text if in toolbar flyout

If I put the Column where the toolbar is hosted to be very big (800) then all the text is visible:
but if I put a smaller column this happens:
But I cannot understand why:
<DataTemplate x:Key="IconFilterButton">
<StackPanel Orientation="Horizontal">
<TextBlock
VerticalAlignment="Center"
Style="{StaticResource LargeIconStyle}"
Text="{Binding}" />
<TextBlock
Margin="6,0,0,0"
VerticalAlignment="Center"
DataContext="{Binding}"
Style="{StaticResource BodyTextStyle}"
Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ToggleButton}, Path=Tag}" />
</StackPanel>
</DataTemplate>
and here the definition
<ToggleButton
x:Name="DFilter"
Click="Filtering_Click"
Content=""
ContentTemplate="{StaticResource IconFilterButton}"
Tag="1d"
/>
<ToggleButton
x:Name="WFilter"
Click="Filtering_Click"
Content=""
ContentTemplate="{StaticResource IconFilterButton}"
Tag="1w"
/>
Even worst if I click on the button once they are out:
and then the text is visible but is wrong as the TextBlock is not considered in the object size:
The WPF ToolBar control uses a custom panel for the overflow Popup. In many styles, the ToolBarOverFlowPanel has a property WrapWidth set to a static value like 200. This determines how many items can be displayed before it wraps to another row in the popup.
I've created custom styling for this control and have found that the ToolBarOverFlowPanel used internally is buggy. That's probably the source of your problem.
You can re-template the ToolBar and wire-up a different value for WrapWidth to try to fix the issue, but my guess is that you'll still run into layout problems.
Otherwise, you might consider making your own replacement control.

Presenting readonly data in a wpf form

I am searching for the "right" way of styling a textbox for showing read-only data.
Normal if you set a textbox to read-only the text somehow become dimed. What I would like is this
See that the data is read-only
Easily read the text
Be able to copy the text
Should be able to see the control if there is no data.
I could give the background or border another color but maybe I am missing out of something? is there a skilled designer out there (-:
For solve this problem you should use RichTextBox inside TextBlock.
Here is my sample of code read-only TextBlock with scrollbar, auto-wrapping and possibility to copy text >
<DockPanel>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<TextBlock IsEnabled="True" TextWrapping="Wrap" TextAlignment="Justify" HorizontalAlignment="Stretch">
<RichTextBox Background="Transparent" BorderThickness="0" IsDocumentEnabled="True" IsReadOnly="True" />
</TextBlock>
</ScrollViewer>
</DockPanel>

Need ability to exit Alt key underline mode, possibly with ESC key

Question: How do you exit keyboard hot-key mode after pressing and releasing the Alt key? In Office the ESC works, in WPF it does not.
Details: I have various Label elements in a WPF application.
<StackPanel>
<Label Grid.Column="0" VerticalAlignment="Center" Content="_Textbox 1" Target="textbox1" />
<TextBox x:Name="textbox1" Width="50" />
<Label Grid.Column="0" VerticalAlignment="Center" Content="T_extbox 2" Target="textbox2" />
<TextBox x:Name="textbox2" Width="50" />
</StackPanel>
When I press and release the Alt key the P stays underlined and I can then separately press the P key and that Label takes its action. This is the same as how Word 2013 and Notepad work in that you don't have to press the Alt and the P at the same time.
Where WPF differs is I cannot press the ESC key to stop the underlining and stop the auto-navigation to Label controls. The only way I see to get out of keyboard navigation mode is to use the mouse and click somewhere, defeating the goal of keyboard navigation.
Adding to my original comment
Actually there is a slight difference in Notepad and Word 2013 behavior. The control's there with the hot-key are in a Menu which takes Focus as soon as you press Alt and you can see they get focus cos the text area caret goes missing and Esc then returns focus to the TextBox while clearing the "_". Now in your sample code if you put the two Label's or even one inside a and then press Alt, you get the same behavior as Word or Notepad. Without the Menu there is no control that wants to take the intermediate focus.
This just seems to be an issue where the Menu gets a deferred focus to handle these hotkeys in it's own FocusManager.IsFocusScope.
Another snippet from MSDN:
The following scenario illustrates how keyboard focus and logical focus change in a Windows Presentation Foundation (WPF) application that has a Window with a TextBox and a Menu which has a MenuItem. When keyboard focus changes from the TextBox to the MenuItem, the TextBox losses keyboard focus but retains logical focus for the Window focus scope. The MenuItem obtains keyboard focus and obtains logical focus for the Menu focus scope. When keyboard focus returns to the root Window, the element in Window focus scope with logical focus will obtain keyboard focus, which in this case is the TextBox. The TextBox now has keyboard focus and logical focus. The MenuItem loses keyboard focus, but retains logical focus for the Menu focus scope.
Solution:
If you just can't stand the fact that you're limited with the grouping requirement imposed by the Menu to achieve the hot-key functionality, you could do something like:
<Grid Margin="25">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="15" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- cannot use Visibility="Collapsed" or "Hidden" on the Menu to make it take focus on Alt press -->
<Menu Width="0"
Height="0">
<Label x:Name="label1"
Content="_Textbox 1"
Target="{Binding ElementName=textbox1}" />
<Label x:Name="label2"
Content="T_extbox 2"
Target="{Binding ElementName=textbox2}" />
<Label x:Name="label3"
Content="Another Loose Label to Link Text_Box 1"
Target="{Binding ElementName=textbox1}" />
</Menu>
<Label Grid.Row="0"
Grid.Column="0"
Content="{Binding ElementName=label1,
Path=Content}" />
<TextBox x:Name="textbox1"
Grid.Row="0"
Grid.Column="1"
Grid.ColumnSpan="2"
Margin="15 0 0 0"
VerticalAlignment="Center" />
<Label Grid.Row="2"
Grid.Column="0"
Content="{Binding ElementName=label2,
Path=Content}" />
<TextBox x:Name="textbox2"
Grid.Row="2"
Grid.Column="1"
Grid.ColumnSpan="2"
Margin="15 0 0 0"
VerticalAlignment="Center" />
<Rectangle Grid.Row="3"
Grid.RowSpan="2"
Grid.Column="1"
Margin="10"
Fill="Tomato" />
<Label Grid.Row="4"
Grid.Column="2"
Content="{Binding ElementName=label3,
Path=Content}" />
</Grid>
So in this setup we do not use any custom Style's for any of the control's. We pretty much create a new top level Menu and add all the desired hot-key Label's to it and set it's Width and Height to 0.
Thus in the actual Visible Grid layout we can position the visible Label's anywhere we choose and to avoid code duplication in specifying the Label.Content twice for each Label(Once in the Menu and next in actual layout) we use a Binding to get the Content for the Visual Label from it's corresponding Label in the Menu.
Update
Reply to OP's comment:
I'm not sure this will be practical in my application. I have hotkeys all over the app with some being duplicates inter-screen. It wouldn't be maintainable to implement this type of workaround.
Well I don't see how duplicates or having stuff all over makes any difference to this tbh.
If you have duplicate hot-key's in multiple Window's, then define Content for these duplicate item's as a String resource in xaml or your .resx you can refer to it everywhere you need it.
Maintainable - Well you do not have anything you do special for maintainability. Your layout is not impacted, your not restricted with anything. If anything you got one <Menu> sitting hidden at the Top level of each of your Window's that defines the hot-keys for that Window and within that Window any control that wants that functionality Binds to the corresponding Menu child item. I think it unifies the scope of hot-keys in a Window to a single place than in multiple different places.
Finally, I ain't trying to impose this approach on you, it's boils down to your personal preference. If your uncomfortable with it then you could get your Label's sub-classed and implement the functionality of deferred focus yourself or raise a Microsoft bug to see if they can maybe address it for you or find an alternate solution or let go of the hot-key functionality all-together.

Move a popup after databinding

I would like to display a popup above my control when the user 'mouse over', problem is that the contents of the popup is a ListBox that databinds so I do not know the size of the control (to set the margins), I have tried every event listed in intellisense on the popup but the ActualHeight of the popup is zero (want to subtract from Margin.Top), any ideas?
For this, I would recommend using a ToolTip. This way you can format the tool tip to show with a list box that is data bound. For example: A normal tooltip would look like:
<sdk:Label Content="{Binding SomeBinding}" Width="Auto" Height="Auto" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<ToolTipService.ToolTip>
<ToolTip Content="Some tool tip." Name="ttSomeToolTip"></ToolTip>
</ToolTipService.ToolTip>
</sdk:Label>
What I assume you're doing is this:
<sdk:Label Content="{Binding SomeToolTip}" Width="Auto" Height="Auto" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<ToolTipService.ToolTip>
<ToolTip Name="ttSomeToolTip">
<ListBox ItemsSource="{Binding MyListBoxSource}" SelectedItem="{Binding MySelectedListBoxItem,Mode=TwoWay}">
</ListBox>
</ToolTip>
</ToolTipService.ToolTip>
</sdk:Label>
I can't guarantee that this proposed solution will work, but you have one of two options: Target the LayoutUpdated event for the ToolTip and do a render transform matrix to resize the tool tip container. Theoretically, the tool tip should resize automatically. So if you're not already using the above mentioned approach, try that and see what happens.
You must run code via Dispatcher, then your code runs in UI thread and you have access to control size.
See here

Windows phone layer

How can I create the effect similar to Windows Phone's MessageBox, where the message gets displayed on a new layer with transparent background, so that the windows becomes modal? My layout is created out of Grid, so I do not know how to add any content over it. Please help.
It's easy to overlay one set of content with another in WPF. Try changing the visibility of the border below, for a simple message box effect. You would of course bind Visibility to your view model, or set it in code behind.
<Grid>
<Grid>
<!-- All your layout here -->
</Grid>
<Border Height="100" Width="100" Background="Azure" Visibility="Hidden">
<TextBlock Text="Hi there" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</Grid>

Resources