wpf textbox DirectionFlow - wpf

Here's the problem. I have a regular textbox that is used for number input to filter items in a list.
<TextBox x:Name="FilterTextBox" Text="{Binding FilterText, UpdateSourceTrigger=PropertyChanged}" Margin="5" />
Now the customer wants this code to be written right to left. I thought that this could be solved with FlowDirection however FlowDirection="RightToLeft" on the box does the same thing as the HorizontalContentAlignment="Right" or TextAlignment="Right" for that matter, meaning that if FlowDirection is "RightToLeft" and I type 3, then 4, then 5, the box will contain "345" aligned to the right, where I had expected it to be "543" aligned to the right, which is also what was requested.
Any idea of to get the desired effect, is FlowDirection supposted to be just a substitute for TextAlignment and I have misunderstood its purpose?
I suppose I could listen to key down event and insert the character at index 0, but I was wondering if there was a cleaner way to do it, all in xaml without code-behind.

Xaml:
<TextBox Name="txtbxExample" Width="100" Height="30" TextChanged="TextBox_TextChanged"/>
Code Behind:
Private Sub TextBox_TextChanged(sender As Object, e As TextChangedEventArgs)
txtbxExample.CaretIndex = 0
End Sub
Tested it out and typing 3 4 5 results in 543. This will probably be the simplest way to do it. Found no way to access the CaretIndex property from within Xaml using triggers, sorry.

Related

WPF, Characters run from right-to-left when input text in TextBox

I have binding in TextBox
<TextBox x:Name="TbxActiveSourceNameSourceNameSourceName" IsEnabled="True" Text="{Binding ViewAudioAudio_ActiveSourceNameModel.ActiveSourceName_SourceName,UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Padding="0,-2,0,0" Height="15" VerticalAlignment="top" Margin="127,10,0,0" FontSize="10" BorderBrush="#FF918D8D" TextAlignment="Center" Width="75px" HorizontalAlignment="Left" HorizontalContentAlignment="Right" />
But characters run from right-to-left.
How do I must to characters run from left-to-right(normal) when I input words in textBox
Many Thanks
I know this is old question but if anyone runs into this issue it happens to deal with
<TextBox Text={..., UpdateSourceTrigger=PropertyChanged}
it seems that when the property changes via keystroke it automatically detects the property change and so it updates the property it's binding to as well. Because of this it resets the cursor to the very left of the textbox rather than leaving where it was last left off.
Or at least I've been only able to reproduce this issue by changing a textbox to textblock and then back to a textbox and changing the UpdateSourceTrigger to a type that isn't PropertyChanged and would correct the issue and have the text flow right to left.
Set the FlowDirection property to LeftToRight. Reference here.

WPF [VB] Bring selected ListViewItem to front and overlap other ListViewItems

I am making an explorer control in my WPF application using a Treeview and Listview. For the Listview I would like to show the contents of the selected folder using 32x32 pixel icons. To achieve this I have the following XAML which is also truncating long file/folder names within a TextBlock:
<ListView x:Name="LV_Explore"
Grid.Column="2"
BorderThickness="0"
VerticalContentAlignment="Top"
ItemsSource="{Binding Path=., Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Visible"
AllowDrop="True">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="SP_ExploreItem"
Width="42">
<Image Source="{Binding LargeIcon, UpdateSourceTrigger=PropertyChanged}"
Margin="0,0,0,2" />
<TextBlock x:Name="TXT_ExploreItem"
Width="42"
Height="42"
TextOptions.TextFormattingMode="Display"
TextAlignment="Center"
TextWrapping="Wrap"
TextTrimming="WordEllipsis"
LineStackingStrategy="BlockLineHeight"
Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
When selecting a ListViewItem I would like for it to overlap the items (files/folders) below rather than the current behaviour which is to increase the height of all of the ListViewItems in the current row of the WrapPanel.
To get to the ListViewItem I am using the following code in order to show all of the text in the TextBlock when an item is selected:
Private Sub LV_Explore_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles LV_Explore.SelectionChanged
If LV_Explore.SelectedItems.Count = 1 Then
Dim LVItem As ListViewItem = TryCast(Me.LV_Explore.ItemContainerGenerator.ContainerFromIndex(Me.LV_Explore.SelectedIndex), ListViewItem)
If LVItem IsNot Nothing Then
Dim BD As Border = TryCast(VisualTreeHelper.GetChild(LVItem, 0), Border)
If BD IsNot Nothing Then
Dim CP As ContentPresenter = TryCast(BD.Child, ContentPresenter)
If CP IsNot Nothing Then
Dim SP As StackPanel = TryCast(LVItem.ContentTemplate.FindName("SP_ExploreItem", CP), StackPanel)
If SP IsNot Nothing Then
Dim TB As TextBlock = TryCast(SP.FindName("TXT_ExploreItem"), TextBlock)
TB.TextTrimming = TextTrimming.None
TB.Height = Double.NaN
End If
End If
End If
End If
End If
End Sub
For reference I want to achieve similar to the behaviour of the desktop e.g: Screenshot 1: Normal state Screenshot 2: Selected state
Whereas I currently have the normal state working fine and the selected state appears like this: Screenshot 3: Listview selected state
I suspect that I may need to change from using a WrapPanel to a Canvas in the ItemsPanelTemplate of the ListView control which will then lose the behaviour of lining up and wrapping items within the Listview automatically. So I am looking for suggestions of the best approach to use here to maintain the layout and to allow me to overlap items when selected.
Thanks,
Jay
As you may realise, something in a listview item is inside a sort of a box and it isn't getting out of that. It will be truncated or clipped if you don't let it grow.
A canvas doesn't clip so that would tick one box of your requirement, you would have to write a custom panel based on a canvas or the base panel control and write your own measure/arrange code.
This is non trivial and any scrolling could make it even more complicated, but you could take a look at people's work:
eg
https://www.codeproject.com/Articles/37348/Creating-Custom-Panels-In-WPF
Alternately, you could use an adorner.
The adorner layer is on top of everything else in your window but still in the same datacontext of whatever it's associated with.
These are not so easy to work with but again you could base your code on someone else's:
http://www.nbdtech.com/Blog/archive/2010/07/12/wpf-adorners-part-4-ndash-simple-and-powerful-system-for.aspx
An adorner would probably be my first candidate, if I follow what you want correctly.
Not many people use vb nowadays and I'm afraid you're going to find pretty much every time you look at samples they are c#.

How do you get a WPF TextBox to overflow to the left and stay that way without messing up your arrow key behavior?

I have a text box that is only 10 characters wide. I need to put 20 characters in it, but only need to show the last 10 characters. I need to force the TextBox to always overflow the text to the left, thus allowing the 10 characters on the right to be visible.
I have looked at several postings and tried all the recommendations I could find, but they don't seem to work properly.
Here are the things I have tried so far (by themselves and in combinations):
<TextBox
HorizontalContentAlignment="Right"
TextAlignment="Right"
FlowDirection="RightToLeft"/>
Seems like FlowDirection is the closest thing to get it to work, but it makes the left and right arrow keys operate backwords.. (you press the left key, the cursor inside the TextBox moves to the right) Also, when you tab off the control after editing the left most text, the text doesn't pop back and show the rightmost characters again.
TextAlignment will just push the text to the right if there isn't enough text to fill the box.
HorizontalContentAlignment doesn't appear to be helping at all...
I made this small example:
First, the XAML of the window:
<Window x:Class="WpfApplication3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<TextBox Text="1234567890" Width="40" Name="MyTextBox" LostFocus="MyTextBox_LostFocus" />
<TextBox Text="" Width="40" Name="MyTextBox2" />
</StackPanel>
</Window>
And some code behind:
private void MyTextBox_LostFocus(object sender, RoutedEventArgs e) {
MyTextBox.ScrollToHorizontalOffset(999999);
}
This will only accomplish what you're looking for when the focus is lost. You may have to call ScrollToHorizontalOffset() after your view is loaded to have the TextBox start off that way. And there might be a better way to determine the parameter. double.MaxValue might be a better choice.

WPF: Textbox Binding with StringFormat={}{0:F2}. Don't show zero's

I am binding an object to a TextBox with the following XAML:
<TextBox Name="MyTextBox" Text="{Binding Path=MyValue, Mode=TwoWay, StringFormat={}{0:F2}}" />
Naturally when I bind a new object (which values are all still zero) the Text property is set to 0.00. I have several of these TextBoxes, which makes it tedious to delete every value before entering a new one.
At the moment I'm clearing these boxes in the Window_Loaded method using the FindVisualChildren method.
It just feels clunky though. Is there a neat way of doing this?
Try the following:
StringFormat={}{0:#.##}
It will format to two decimal places and won't show zeroes.

Display a running number in the WPF DataGrid RowHeader

I am using WPF with MVVM.
How can I bind:
a list of numbers
or a list of clr objects with property number
or a list of strings
in my ViewModel to the RowHeader of the WPF DataGrid ?
I found an elegant solution for this problem from http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/7d0cbdf2-dea3-4dd4-a570-08aa6c78d911. Here is recap:
<tk:DataGrid x:Name="dg" LoadingRow="dg_LoadingRow" ItemsSource="{Binding}">
<tk:DataGrid.RowHeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type tk:DataGridRow}}, Path=Header}"></TextBlock>
</DataTemplate>
</tk:DataGrid.RowHeaderTemplate>
</tk:DataGrid>
private void dg_LoadingRow(object sender, Microsoft.Windows.Controls.DataGridRowEventArgs e)
{
e.Row.Header = (e.Row.GetIndex() + 1).ToString();
}
However, I couldn't make the number on the row header right aligned. Adding HorizontalAlignment="Right" to the TextBlock doesn't help. I also tried to wrap the TextBlock inside a StackPanel, and set this property, but it doesn't work either. Any idea?
You could take this approach http://www.codeproject.com/KB/WPF/MVVM_DataGrid.aspx?msg=3241301
Basically you are creating an list that will handle the numbering for you, as long as the object of T implements ISequenceObject.
If you wanted to go the other direction you could look at handling the LoadingRow Event and simply adding 1 to a known DataColumn. This would not break the concept of MVVM as a numbered column is not part of the business logic, but part of the presentation.
To make the Numbered DataGrid reusable you could also inherit from the DataGrid and create you own Numbered DataGrid.

Resources