Workaround for caret textbox with binding an property changed XAML - wpf

I have a lot of textboxes binded in twoway mode ot a different properties with UpdateSourceTrigger=PropertyChanged and I have one annoying problem: when I enter or delete a value - caret moves to the begin of the string.
I found a solution here:
TextBox with CurrencyFormat and PropertyChanged trigger doesn't accept text right
but I cannot implement it correctly. I probably miss something.
Here is my XAMLbinding for one of textboxes:
enter code here <TextBox x:Name="TextBoxFirstPersonCameraMinPosY" Width="150" VerticalAlignment="Center" FontWeight="Normal"
Text="{Binding Path=CameraLimitationParameters.FirstPersonCameraPosition.MinValue.Y, Mode=TwoWay, IsAsync=True, Delay=0, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource ToStringConverter}}" Style="{StaticResource {x:Type TextBox}}"
MaxLength="40" Margin="10,0,0,0" MinWidth="150" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled" MaxWidth="150"></TextBox>
and here is my style:
enter code here<Page.Resources >
<ObjectDataProvider x:Key="CameraMode"
MethodName="GetValues" ObjectType="{x:Type sys:Enum}" >
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="settingsManager:CameraBehavior"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<settingsManager:ToStringConverter x:Key="ToStringConverter"></settingsManager:ToStringConverter>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="Text" Value="{Binding UpdateSourceTrigger=PropertyChanged}"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</Page.Resources>
What did I miss an how to apply this style for all textboxes independently of binding property without duplicating code?
And will this workaround work for my case? Help me please.

Problem was because I set IsAsync=True in TextBox. In this case Async need to be set to false.

Related

WPF XAML x:Type is underlined and states "MyColor" does not exist in the namespace .... Why?

I'm trying to display on a DataGrid a ObservableCollection. For each item in the ObservableCollection, I have a ComboBox that displays the currently selected item (MyColor in my example) and lets the user choose a different color from the combobox. This was working reasonably well when my Enum MyColor was in the same namespace as the MainWindow. However, to make the example closer to the problem I'm actually trying to solve I put the MyColor enum in a different project and namespace. I've included all code. In the XAML for the mainwindow, I have a ObjectDataProvider and the line
<x:Type TypeName="enu:MyColor" />
The word x:Type is underlined and has the message: The name MyColor does not exist in the namespace "clr-namespace:Library.EnumDefinitions;assembly=Library.EnumDefinitions"
I've double and triple checked spelling, but don't see the problem. MyColor is defined in the namespace Library.EnumDefinitions. I'm wondering if the fact that the enum is in a separate namespace and project is causing me grief. The idea of using ObjectDataProvider can by found here for example:
https://brianlagunas.com/a-better-way-to-data-bind-enums-in-wpf/
The suggestion that there might be something special going on if your enum is in a different project/namespace is given here:
The name does not exist in the namespace in WPF application
I do have a reference to the different project in my Main project.
Any idea what is going on? If I can provide other information, please let me know.
Thanks,
Dave
MainWindow XAML
<Window x:Class="TrickyBindingProblems.MainWindow"
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"
xmlns:enu="clr-namespace:Library.EnumDefinitions;assembly=Library.EnumDefinitions"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<ObjectDataProvider x:Key="EnumDataProvider" MethodName="GetValues"
ObjectType="{x:Type sys:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="enu:MyColor" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
<Grid>
<DataGrid Grid.Column="1"
Margin="0"
HorizontalAlignment="Left"
AutoGenerateColumns="False"
Background="Transparent"
DataContext="{Binding}"
HeadersVisibility="Column"
ItemsSource="{Binding Cars}"
SelectedItem="{Binding SelectedItemProperty, Mode=TwoWay}"
RowBackground="Transparent"
RowHeight="30">
<DataGrid.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Foreground" Value="Black" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{x:Null}" />
<Setter Property="BorderBrush" Value="{x:Null}" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.CellStyle>
<DataGrid.ColumnHeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="FontWeight" Value="Bold" />
</Style>
</DataGrid.ColumnHeaderStyle>
<DataGrid.Columns>
<DataGridTemplateColumn Width="*" Header="Make">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock VerticalAlignment="Center"
Padding="5"
Text="{Binding Make}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="*" Header="Color (as ComboBox)">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Source={StaticResource EnumDataProvider}}" SelectedItem="{Binding Color, Mode=TwoWay}">
<ComboBox.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="Black" />
</Style>
</ComboBox.Resources>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
namespace Library.EnumDefinitions
{
public enum MyColor
{
Red,
Blue,
Green
}
}
UPDATE!!!
I believe I fixed my immediate problem. I changed the line:
xmlns:enu="clr-namespace:Library.EnumDefinitions;assembly=Library.EnumDefinitions"
to:
xmlns:enu="clr-namespace:Library.EnumDefinitions"
Can someone tell me when you are suppose to use the "assembly" part and when you are not?

Why are ListViewItems within ContentControl only selectable on first few pixels?

I want to request different types of properties from the user of my WPF application. Therefore I have a ListView thats ItemsSource binds to an ObservableCollection<PropertiesBase>. Each property derives from PropertiesBase. As an expert user should be able to edit these properties, the DataTemplate is selected depending on the EditMode Property and the type of the property.
Data display and everything else works fine, except that I am not able to select a ListViewItem. Only when I click a textbox inside a ListViewItem or the first few pixels of the item I am able to select an item.
The selection only works on the white part of the item
I have tried to play around with Focusable but it does not led me to success. I also copied my xaml of the ListViewItem directly into the Listview (without datatemplate). That worked as expected.
ListView XAML:
<ListView ItemsSource="{Binding PropertyList}" HorizontalContentAlignment="Stretch" SelectionMode="Single">
<ListView.Resources>
<DataTemplate DataType="{x:Type properties:PasswordProperty}">
<ContentControl Content="{Binding}" Background="Red">
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Setter Property="ContentTemplate" Value="{StaticResource PasswordPropertyListViewItem}" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=DataContext.EditMode, RelativeSource= {RelativeSource FindAncestor, AncestorType={x:Type ListView}}}" Value="True">
<Setter Property="ContentTemplate" Value="{StaticResource EditPasswordPropertyListViewItem}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
Example ListViewItem XAML that is referenced by DataTemplate:
<ListViewItem x:Class="PasswordPropertyListViewItem"
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">
<Border BorderThickness="0,0,0,1" BorderBrush="DarkGray">
<DockPanel LastChildFill="True" HorizontalAlignment="Stretch">
<Label Margin="8" Content="{Binding PropertyName}"></Label>
I expect that it does not matter where I click onto the ListViewItem but the item is selected in any case (Especially the red part of the image above).
Clemens provided a solution in his comment above.
I indeed nested two ListViewItems.
The solution is to change the type of my templated control to ContentControl.
<ContentControl x:Class="PasswordPropertyListViewItem"
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">
<Border BorderThickness="0,0,0,1" BorderBrush="DarkGray">
<DockPanel LastChildFill="True" HorizontalAlignment="Stretch">
<Label Margin="8" Content="{Binding PropertyName}"></Label>
Thanks Clemens!

DataTriggers : How it works

I want to implement a DataTrigger for say, textBox1. When Text inside textBox1 is "ABC" then I want to display "Data matched!" in another TextBox say, textBox2. I have written below xaml code for this but its not working. I am getting below error message.
'Text' member is not valid because it does not have a qualifying type name
XAML code for this is:
<Window x:Class="ControlTemplateDemo.Animation"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="Animation" Height="300" Width="607">
<Grid>
<Border Background="White">
<StackPanel Margin="30" HorizontalAlignment="Left" Width="500" Height="209">
<TextBox Name="textBox1">
<TextBox.Triggers>
<DataTrigger Binding="{Binding Path=Text}">
<DataTrigger.Value>
<sys:String>ABC</sys:String>
</DataTrigger.Value>
<Setter TargetName="textBox2" Property="Text" Value="Data matched!"/>
</DataTrigger>
</TextBox.Triggers>
</TextBox>
<TextBox Name="textBox2">
</TextBox>
</StackPanel>
</Border>
</Grid>
</Window>
Is there any problem in binding?
Thanks,
Hemant
You need to give the DataTrigger in a Style for the second TextBox
something like:
<StackPanel>
<TextBox x:Name="inputBox" />
<TextBox Margin="0 25 0 0">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Text"
Value="No Match Found" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=inputBox,
Path=Text}"
Value="ABC">
<Setter Property="Text"
Value="Match Found" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</StackPanel>
TextBox.Triggers does not support DataTrigger. I'd guess it's only for EventTriggers as the documentation states
on a side-note, I normally have my bindings in the element that ends up as the target(as much as I can). This way I find it easier to debug at-least personally. If the TextBox has wrong info I instantly check it's binding than every binding in my xaml file to see which element has a wrong binding that ends up updating my TextBox.

TextBox with CurrencyFormat and PropertyChanged trigger doesn't accept text right

I have a TextBox in a WPF window bound to a dependency property of the window of type double (see below). Whenever the user types in the TextBox when
The TextBox is empty, or
All of the text is selected,
the typed text is accepted incorrectly. For example: If I type a '5' in either of these scenarios, the resulting text is "$5.00", but the caret is located before the '5', after the '$'. If I try to type "52.1", I get "$2.15.00".
<Window x:Class="WPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="154" Width="240" Name="ThisWindow"
Background="{StaticResource {x:Static SystemColors.AppWorkspaceBrushKey}}">
<Grid>
<TextBox Text="{Binding ElementName=ThisWindow,
Path=Amount,
StringFormat={}{0:c},
UpdateSourceTrigger=PropertyChanged}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
MinWidth="100" />
</Grid>
</Window>
If I remove the UpdateSourceTrigger attribute, it types correctly, but doesn't maintain the currency format.
Any ideas?
This is caused by it trying to apply the formatting after every character press.
As an alternative, I usually just style the TextBox so it only applies formatting when it's not being edited
<Style TargetType="{x:Type TextBox}">
<Setter Property="Text" Value="{Binding SomeValue, StringFormat=C}" />
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="Text" Value="{Binding SomeValue, UpdateSourceTrigger=PropertyChanged}" />
</Trigger>
</Style.Triggers>
</Style>

remove red rectangle around combobox

i need to remove red rectangle around combobox. I have setup combobox in xaml like (below) this and i`m trying to override of the Validation.ErrorTemplate.
<ComboBox x:Name="comboPodkategoria"
Margin="0,3,0,0"
IsSynchronizedWithCurrentItem="False"
IsEditable="False"
ItemsSource="{Binding Source={StaticResource PodKategoriaLookup}, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"
SelectedValue="{Binding IDPodKategoria}"
DisplayMemberPath="kat_popis" SelectedValuePath="IDPodkat" TabIndex="5" Style="{StaticResource combostyle}">
<Validation.ErrorTemplate>
<ControlTemplate>
</ControlTemplate>
</Validation.ErrorTemplate>
</ComboBox>
And style for removing red rectangle, but a have some error in xaml saying that Visibility property is not recognized or is not accessible. Style definition is below.
<Style x:Key="combostyle">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="Visibility" TargetName="NotValid" Value="Visible"/>
</Trigger>
</Style.Triggers>
Any idea? :(
Use this to modify the Validation.ErrorTemplate
<ControlTemplate x:Key="ComboBoxValidationErrorTemplate">
<DockPanel>
<Border BorderBrush="Blue" BorderThickness="4">
<AdornedElementPlaceholder />
</Border>
</DockPanel>
</ControlTemplate>
And then use it in your ComboBox like
<ComboBox Validation.ErrorTemplate="{StaticResource ComboBoxValidationErrorTemplate}"
...>
To have no indication of a Validation Error, remove the DockPanel, set Visibility to Collapsed or any other way you like.
Almost forgot, probably the easiest way to remove the "Red Border"
<ComboBox Validation.ErrorTemplate="{x:Null}"
...>
Add your Combobox, Validation.ErrorTemplate="{x:Null}" ; this code is ignore errors.
The setter in your trigger is setting the Visibility property of an element named "NotValid". That is not defined in the XAML you posted. If there is no element named "NotValid", that is your problem.

Resources