I was tying to set focus on a TextBox used to build a customized "Numeric Up Down" control.
This is the custom "Numeric Up Down"
<Style x:Key="SpinButton" TargetType="Slider" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Slider">
<Border Grid.RowSpan="3" BorderThickness="1,1,1,1" BorderBrush="WhiteSmoke">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".5*"/>
<ColumnDefinition Width=".5*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height=".5*"/>
<RowDefinition Height=".5*"/>
</Grid.RowDefinitions>
<TextBox Name="textBoxNumericUpDown" Grid.RowSpan="3" Margin="2,0,0,0" Text="{Binding Value,Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" FontSize="20" VerticalAlignment="Center" Background=" {x:Null}" Foreground="White" BorderThickness="0" CaretBrush="White" IsTabStop="True"/>
<RepeatButton Grid.Column="1" Grid.Row="0" Margin="0,0,-5,0" Command="Slider.IncreaseLarge" Style="{StaticResource TimeRepeatButtonStyle}" Content="+" Background="{x:Null}" BorderBrush="White" Foreground="White" FontSize="18" Cursor="Hand" Width="44" Height="44" IsTabStop="False"/>
<RepeatButton Grid.Column="1" Grid.Row="1" Command="Slider.DecreaseLarge" Margin="0,1,-5,0" Style="{StaticResource TimeRepeatButtonStyle}" Content="-" Background="{x:Null}" BorderBrush="White" Foreground="White" FontSize="18" Cursor="Hand" Width="44" Height="44" IsTabStop="False"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Usage
<Slider PreviewTextInput="textBoxTimeMinute_PreviewTextInput" Name="textBoxTimeMinute" Width="100" Style="{StaticResource SpinButton}" Maximum="999" Margin="8" HorizontalAlignment="Left" Minimum="0" IsTabStop="True" TabIndex="0"/>
<Label Grid.Column="1" Content=":" VerticalAlignment="Center" IsTabStop="False"/>
<Slider PreviewTextInput="textBoxTimeSecond_PreviewTextInput" Grid.Column="2" Name="textBoxTimeSecond" Width="100" Style="{StaticResource SpinButton}" Maximum="60" Margin="8" HorizontalAlignment="Left" Minimum="-1" IsTabStop="True" TabIndex="1"/>
Wanted result (Automatic focus on the first textbox if no number inside)
Wanted result (Automatic focus on the first textbox if number inside, number is selected)
I tried different ways to make it select the correct Control, but it always selects the outer layer. In my case The Grid/Border.
Only after I press TAB I can have it select the correct TextBox Control.
Is there any way in WPF I can achieve the focus on textbox without pressing TAB?
Solved:
If you want to focus a TextBox inside a ControlTemplate you have to set up a trigger on the "IsFocused" property.
When it becomes true then you have to set the FocusManager.FocusedElement field to the name of the TextBox (or other control) you want to focus.
Below is the code I used to achieve this:
<ControlTemplate TargetType="Slider">
<TextBox x:Name="TextBoxToFocus"/> //The textbox(or any other element) I want to set focus to. It is very important to have it named, otherwise I won't know which control to focus.
<ControlTemplate.Triggers> //The trigger
<Trigger Property = "IsFocused" Value = "True" /> //The property the trigger is watching
<Setter TargetName="TextBoxToFocus" Property="FocusManager.FocusedElement" Value="{Binding ElementName=NumericUpDown}"/> //Setter when the trigger executes
</Trigger>
</ControlTelmplate.Triggers>
Related
the environment:
Visual Studio 17.4.3
Dotnet 7 v101
Mvvm Community 8.0
When I try on windows application to use a slider in a list view the slider doesn't get binded correctly to the items of the list view (at least my uneducated guess). The slider looks to be in de default state.
i have a model for changeable properties like this:
public class ChangeableProperty {
public int MinValue {get;set;}
public int MaxValue {get;set;}
public int Value {get;set;}
}
[ObservableProperty]
IEnumerable<ChangeableProperty> dynamicProperties;`
I get them from the backend and try to show them in the Maui App using Mvvm Toolkit.
The ListView is showing and in the first column I added some labels to show the values.
When using the slider the values are not used.
The source is
<ListView ItemsSource="{Binding DynamicProperties, Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="imaging:ChangeableProperty">
<ViewCell>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="50*"/>
</Grid.ColumnDefinitions>
<Label Grid.Row="0"
Grid.Column="0"
Text="{Binding Name}"
FontAttributes="Bold"/>
<Label Grid.Row="1"
Grid.Column="0"
Text="{Binding Value, Mode=OneWay}"
FontAttributes="Italic"/>
<Label Grid.Row="2"
Grid.Column="0"
Text="Min"
FontAttributes="Bold"/>
<Label Grid.Row="3"
Grid.Column="0"
Text="{Binding StartValue, Mode=OneWay}"
FontAttributes="Italic"/>
<Label Grid.Row="4"
Grid.Column="0"
Text="Max"
FontAttributes="Bold"/>
<Label Grid.Row="5"
Grid.Column="0"
Text="{Binding EndValue, Mode=OneWay}"
FontAttributes="Italic"/>
<Slider Grid.Column="1"
Grid.Row="0"
Grid.RowSpan="4"
x:Class="ChangeableProperty"
Minimum="{Binding MinValue}"
Maximum="{Binding MaxValue}"
VerticalOptions="Center"
Value="{Binding Value, Converter{StaticResource DoubleToIntConverter}}"
MinimumTrackColor="Red"
MaximumTrackColor="Blue"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
<ListView>
The slider appears to have the default settings. Is it possible to have the changed in a property notified? The demos I saw are related to showing only the list (so when entries available show them) but not for editing using a slider.
Is this a known issue or is it not possible to use a slider in a list view like this?
Kind regards
Yes, this issue can be replicated when setting binding to the Slider. The binding value of the Slider fails to change when using binding. This issue looks similar to an existing one in Github:Setting Slider.Maximum or Slider.Minimum resets binding of Slider.Value. You can follow up there.
Also, you can raise a new issue on Github via this link:https://github.com/dotnet/maui/issues/new/choose
In xamarin Android we have "Visibility.Gone;" to hide the button. In Xamarin Forms we have IsVisible="{Binding State}", but this only will make view invisible, space remain there.
Please let me know solution.
Regards
In your view model you need to have something similar to the following:
public bool State{
get {
return _state;
}
set {
_state= value;
RaisePropertyChanged ("State");
}
}
According to the Xamarin documentation found here the element should be removed from the visual tree and not take up any space.
Edit:
I'm not sure how you're setting the Column="5" on your grid. There is no attribute for Grid that contains column; however, I am able to produce the effect you looking for with the following code.
<Grid BackgroundColor="Gray">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<Grid.Padding>
<OnPlatform x:TypeArguments="Thickness" iOS="0,-3,-20,-3" Android="0, -5, 0, -5" WinPhone="20, 20, 20, 20" />
</Grid.Padding>
<BoxView Color="Blue" Grid.Column="0"></BoxView>
<BoxView Color="Green" Grid.Column="1" IsVisible="{Binding State}"></BoxView>
<BoxView Color="Blue" Grid.Column="2"></BoxView>
<BoxView Color="Green" Grid.Column="3"></BoxView>
</Grid>
Details:
You are correct in that setting the label visibility to false in a grid will maintain the space allocated to the control in the grid. What you can do is set the grid <ColumnDefinition Width="Auto" /> or <RowDefinition Height="Auto" /> and put your label into that column or row. This will automatically remove the space allocated for the control when the visibility is set to false. Below is a screenshot of the effect you are getting (left) and the effect after setting the Definition to Auto (right).
I have a LongListSelector and I want to add a Flick gesture to it. I want to mimic iOS swipe to delete action.
I only managed to add the Flick event to the whole LongListSelector, but I couldn't get the item the event happend on.
UPDATE
Here's how I managed to do it in case anyone needs it:
<phone:PhoneApplicationPage.Resources>
<DataTemplate x:Key="dataTemplate" >
<Grid x:Name="Main" Margin="0,0,0,5" VerticalAlignment="Center" Tag="{Binding}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<toolkit:GestureService.GestureListener>
<toolkit:GestureListener Flick="GestureListener_Flick"/>
</toolkit:GestureService.GestureListener>
<StackPanel Orientation="Horizontal" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Stretch">
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" Margin="0,0,0,0">
<StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Center">
<TextBlock Text="{Binding name}" TextTrimming="WordEllipsis" Style="{StaticResource PhoneTextNormalStyle}" FontSize="28" HorizontalAlignment="Stretch"/>
<TextBlock Text="{Binding description}" MaxWidth="420" TextWrapping="Wrap" Margin="12,0" Style="{StaticResource PhoneTextSubtleStyle}" HorizontalAlignment="Stretch"/>
</StackPanel>
</StackPanel>
</StackPanel>
<StackPanel Grid.Column="1" x:Name="LeftPanel" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Name="deleteBtn" Visibility="{Binding showDelete, Converter={StaticResource VisibilityConverter}}" Content="Delete" HorizontalAlignment="Right" VerticalAlignment="Center"/>
</StackPanel>
</Grid>
</DataTemplate>
</phone:PhoneApplicationPage.Resources>
<toolkit:LongListSelector Grid.Row="0" HorizontalAlignment="Stretch" x:Name="data" Background="Transparent"
GroupHeaderTemplate="{StaticResource groupHeader}"
GroupItemTemplate="{StaticResource itemHeader}"
ItemTemplate="{StaticResource meetingItemTemplate}">
</toolkit:LongListSelector>
and in the code you bind your LongListSelector to whatever you want.
I have a listbox with for data templates, and I want to disable the tilt effect on one of the data templates, but it is not working... this is what I've been trying:
<ListBox ScrollViewer.VerticalScrollBarVisibility="Disabled" x:Name="MainListBox" Margin="0,10,0,0" SelectionChanged="MainListBoxSelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<local:Datatemplates Content="{Binding}">
<local:Datatemplates.ThirdItem>
<DataTemplate>
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="0,10" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="1" toolkit:TiltEffect.SuppressTilt="True">
<TextBlock Text="{Binding Title}" TextWrapping="NoWrap" FontSize="{StaticResource PhoneFontSizeExtraLarge}" Style="{StaticResource PhoneTextGroupHeaderStyle}" toolkit:TiltEffect.SuppressTilt="True"/>
<TextBlock Text="{Binding SubTitle1}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSmallStyle}" toolkit:TiltEffect.SuppressTilt="True"/>
<TextBlock Text="{Binding SubTitle2}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSmallStyle}" toolkit:TiltEffect.SuppressTilt="True"/>
</StackPanel>
</Grid>
</DataTemplate>
</local:Datatemplates.ThirdItem>
</local:ProfileSetupDatatemplates>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I already tried to put the suppress tilt effect everywhere it wasn't working.
What am I missing
TiltEffect is only applied to button controls (Button, CheckBox, etc.) and ListBoxItems, so trying to suppress it on a Stackpanel won't work.
So:
you should be able to tweak your template like so:
<DataTemplate>
<ListBoxItem toolkit:TiltEffect.SuppressTilt="True" >
...your code
</ListBoxItem>
</DataTemplate>
I have a listbox bound to a view model property called Choices. Each choice has a label and an index. I need to bind the buttons in the list to a command on the same view model. So far Ive figured out this much:
<ListBox Grid.Row="1" ItemsSource="{Binding Choices}" SelectedIndex="{Binding SelectedChoice, Mode=TwoWay}" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch" Margin="1">
<Button Content="{Binding Caption}" Height="24" HorizontalAlignment="Stretch"
Command="{Binding RelativeSource={RelativeSource ???},
Path=SelectChoice}" CommandParameter="{Binding}"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I cant figure out what RelativeSource to use for the command and I'm not sure the CommandParameter is correct.
This seems a really simple thing to do but it's obviously too simple for my poor old brain. Can anyone help please?
Thanks
Sorted:
<ItemsControl Grid.Row="1" ItemsSource="{Binding Choices}" >
<ItemsControl.ItemsPanel >
<ItemsPanelTemplate >
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
</StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Caption}" Height="24" HorizontalAlignment="Stretch" Margin="0,0,4,0"
Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemsControl}}, Path=DataContext.SelectChoice}"
CommandParameter="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>