I have run into a problem with the listpicker. I have a settings page with a option called "Decimals" where you can toggle a "Toggleswitch" and if you turn the toggle on, the listpicker gets enabled. Now when you click on the listpicker, you can choose from 1 to 5 as the amount of decimals. If you choose for example the number "3" in the listpicker, it will get saved to a key on isolated storage with the value 3, if you go to the MainPage it will check the isolatedstorage and if it contains the value "3", it will set a textblock to use 3 decimals. If I then go to my Settings page again, the app crashed with the message "SelectedIndex must always be set to a valid value." Where it should have showed the correct value that was chosen in the listpicker
Here is the code I use:
Settings.XAML:
<phone:PhoneApplicationPage
xmlns:local="clr-namespace:Vaterpas"
x:Class="Vaterpas.Settings"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d"
shell:SystemTray.IsVisible="True">
<phone:PhoneApplicationPage.Resources>
<local:Decimals x:Key="Decimals"/>
<DataTemplate x:Name="lpkFullItemTemplate">
<TextBlock FontSize="36" Text="{Binding}" />
</DataTemplate>
</phone:PhoneApplicationPage.Resources>
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="100"/>
<RowDefinition Height="120"/>
<RowDefinition Height="100"/>
<RowDefinition Height="100"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="285">
</ColumnDefinition>
<ColumnDefinition>
</ColumnDefinition>
</Grid.ColumnDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel Grid.ColumnSpan="2" Grid.Row="0" Margin="12,17,0,28">
<TextBlock Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock Text="Indstillinger" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<Grid Grid.Column="2" Grid.Row="2">
<toolkit:ToggleSwitch Click="tglDecimals_Click" VerticalAlignment="Top" Height="90" Name="tglDecimals" Content="" Margin="0,10,10,0"></toolkit:ToggleSwitch>
<Grid DataContext="{StaticResource Decimals}">
<toolkit:ListPicker x:Name="lpkDecimals" ItemsSource="{Binding decimals}" FullModeHeader="Antal decimaler" FullModeItemTemplate="{StaticResource lpkFullItemTemplate}" ExpansionMode="FullScreenOnly" IsEnabled="False" Margin="130,60,20,0" SelectionChanged="lpkDecimals_SelectionChanged"></toolkit:ListPicker>
</Grid>
</Grid>
Settings.cs
namespace Vaterpas
{
public partial class Settings : PhoneApplicationPage
{
protected IsolatedStorageSettings m_Settings = IsolatedStorageSettings.ApplicationSettings;
protected const string TOGGLE_DECIMALS_SETTING_KEY = "ToggleDecimals";
protected const string DECIMALS_SETTING_KEY = "Decimals";
public Settings()
{
InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (m_Settings.Contains(TOGGLE_DECIMALS_SETTING_KEY))
{
string decimalsToggleValue = (string)m_Settings[TOGGLE_DECIMALS_SETTING_KEY];
string decimalsValue = (string)m_Settings[DECIMALS_SETTING_KEY];
if (decimalsToggleValue == "On")
{
lpkDecimals.IsEnabled = true;
tglDecimals.IsChecked = true;
tblDecimals.Text = "On";
if (decimalsValue == "1")
{
lpkDecimals.SelectedIndex = 0; // HERE IT CRASHES, WITH THE ERROR (SelectedIndex must always be set to a valid value.")
}
else if (decimalsValue == "2")
{
lpkDecimals.SelectedIndex = 1; // HERE IT CRASHES, WITH THE ERROR (SelectedIndex must always be set to a valid value.")
}
else if (decimalsValue == "3")
{
lpkDecimals.SelectedIndex = 2; // HERE IT CRASHES, WITH THE ERROR (SelectedIndex must always be set to a valid value.")
}
else if (decimalsValue == "4")
{
lpkDecimals.SelectedIndex = 3; // HERE IT CRASHES, WITH THE ERROR (SelectedIndex must always be set to a valid value.")
}
else if (decimalsValue == "5")
{
lpkDecimals.SelectedIndex = 4; // HERE IT CRASHES, WITH THE ERROR (SelectedIndex must always be set to a valid value.")
}
}
else
{
tglDecimals.IsChecked = false;
tblDecimals.Text = "Off";
lpkDecimals.IsEnabled = false;
}
}
else
{
tglDecimals.IsChecked = false;
tblDecimals.Text = "Off";
}
base.OnNavigatedTo(e);
}
private void tglDecimals_Click(object sender, RoutedEventArgs e)
{
if (tglDecimals.IsChecked == true)
{
lpkDecimals.IsEnabled = true;
tblDecimals.Text = "On";
m_Settings[TOGGLE_DECIMALS_SETTING_KEY] = "On";
lpkDecimals.SelectedIndex = 0;
m_Settings[DECIMALS_SETTING_KEY] = "1";
}
else
{
lpkDecimals.IsEnabled = false;
tblDecimals.Text = "Off";
m_Settings[TOGGLE_DECIMALS_SETTING_KEY] = "Off";
m_Settings[DECIMALS_SETTING_KEY] = "0";
}
}
private void lpkDecimals_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// Make sure we don't handle the event during initiation.
if (e.RemovedItems != null && e.RemovedItems.Count > 0)
{
if (this.lpkDecimals.SelectedItem != null)
{
m_Settings[DECIMALS_SETTING_KEY] = lpkDecimals.SelectedItem.ToString();
}
}
}
}
public class Decimals
{
public IEnumerable<string> decimals { get { return "1,2,3,4,5".Split(','); } }
}
}
ERROR: SelectedIndex must always be set to a valid value.
I really hope there is someone that can help me with this problem.
I think the the ItemSource is taking time to get assigned to the listpicker as it is assigned in xaml and OnNavigatedTo sometimes runs before InitializeComponent(); method which loads the xaml, and Selected Index property is getting assigned in OnNavigatedTo which is the reason for your error.
Remove the assignment of itemsource from .xaml and Try assigning it in OnNavigatedTo itself before all your coded stuff.
Like this :-
protected override void OnNavigatedTo(NavigationEventArgs e)
{
tglDecimals.ItemSource=Your List;
if (m_Settings.Contains(TOGGLE_DECIMALS_SETTING_KEY))
{
string decimalsToggleValue = (string)m_Settings[TOGGLE_DECIMALS_SETTING_KEY];
string decimalsValue = (string)m_Settings[DECIMALS_SETTING_KEY];
if (decimalsToggleValue == "On")
{
lpkDecimals.IsEnabled = true;
tglDecimals.IsChecked = true;
tblDecimals.Text = "On";
if (decimalsValue == "1")
{
lpkDecimals.SelectedIndex = 0; // HERE IT CRASHES, WITH THE ERROR (SelectedIndex must always be set to a valid value.")
}
else if (decimalsValue == "2")
{
lpkDecimals.SelectedIndex = 1; // HERE IT CRASHES, WITH THE ERROR (SelectedIndex must always be set to a valid value.")
}
else if (decimalsValue == "3")
{
lpkDecimals.SelectedIndex = 2; // HERE IT CRASHES, WITH THE ERROR (SelectedIndex must always be set to a valid value.")
}
else if (decimalsValue == "4")
{
lpkDecimals.SelectedIndex = 3; // HERE IT CRASHES, WITH THE ERROR (SelectedIndex must always be set to a valid value.")
}
else if (decimalsValue == "5")
{
lpkDecimals.SelectedIndex = 4; // HERE IT CRASHES, WITH THE ERROR (SelectedIndex must always be set to a valid value.")
}
}
else
{
tglDecimals.IsChecked = false;
tblDecimals.Text = "Off";
lpkDecimals.IsEnabled = false;
}
}
else
{
tglDecimals.IsChecked = false;
tblDecimals.Text = "Off";
}
base.OnNavigatedTo(e);
}
This Would Help
First have a property for selected index just to check like this--
int lpkSelectedIndex=0;
public int LpkSelectedIndex
{
get
{
return this.lpkSelectedIndex;
}
set
{
this.lpkSelectedIndex= value;
}
}
After that bind this property in xaml like this.And remember bind this after Itemsource property and try it.
<toolkit:ListPicker x:Name="lpkDecimals" ItemsSource="{Binding decimals}" FullModeHeader="Antal decimaler" FullModeItemTemplate="{StaticResource lpkFullItemTemplate}" ExpansionMode="FullScreenOnly" IsEnabled="False" Margin="130,60,20,0" SelectionChanged="lpkDecimals_SelectionChanged" SelectedIndex="{Binding LpkSelectedIndex, Mode=TwoWay}"></toolkit:ListPicker>
Related
I am trying to write a game for myself using Xamarin. The problem is that I can't make the colors dynamically change after the start button is pressed. At first I tried to do it through the BackgroundColor property, but because it didn't work, I decided to use dynamic resources, but that doesn't work either. Please help me find a mistake in the code or algorithm.
P.s
The idea of the game is this: to reproduce a sequence of colors from memory, the difficulty gradually increases: at first only one button is highlighted, then there are already two buttons, and so on. Victory is achieved if you accurately reach the 20th stage (reproduce a sequence of 20 colors) and complete it.
P.p.s
I ran the app on my phone - Xiaomi Poco X3 NFC, my OS is MIUI 12 (Android 10).
MainPage.xaml.cs
using System;
using System.Threading;
using Xamarin.Forms;
namespace JustRepeat
{
public partial class MainPage : ContentPage
{
public readonly MethodsCollection methodsCollection;
public readonly Button[] buttonsMas;
public MainPage()
{
InitializeComponent();
methodsCollection = new MethodsCollection(this);
buttonsMas = new Button[] { one, two, three, four, five, six, seven, eight, nine };
}
private void Button_Clicked(object sender, EventArgs e)
{
methodsCollection.PlaySequence();
startstop.IsEnabled = false;
}
private void Buttons_Clicked(object sender, EventArgs e)
{
bool result = methodsCollection.CheckSequence((Button)sender, out int currStg);
if (!result)
{
DisplayAlert("Notification", $"You lose.\nThe last passed stage: {currStg}.", "OK");
startstop.IsEnabled = true;
return;
}
else if (result & currStg == 20)
{
DisplayAlert("Notification", "You won!", "OK");
startstop.IsEnabled = true;
}
}
}
public class MethodsCollection
{
private readonly MainPage mainPage;
private Color[] colors;
private int[] sequence;
private int currentStage = 1;
private int currentMember = 0;
public MethodsCollection(MainPage mP)
{
mainPage = mP;
}
private int[] GenerateSequence(int currentNumber)
{
Random random = new Random();
int[] posMas = new int[currentNumber];
for (int i = 0; i < posMas.Length; i++)
{
posMas[i] = random.Next(1, 10);
}
return posMas;
}
public void PlaySequence()
{
Random random = new Random();
sequence = GenerateSequence(currentStage);
colors = new Color[currentStage];
for (int i = 0; i < sequence.Length; i++)
{
colors[i] = Color.FromRgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256));
mainPage.Resources[string.Format("{0}", sequence[i])] = colors[i];
Thread.Sleep(1000);
mainPage.Resources[string.Format("{0}", sequence[i])] = Color.LightGray;
}
}
public bool CheckSequence(Button btn, out int stage)
{
int pos = 0;
for (int i = 0; i < mainPage.buttonsMas.Length; i++)
{
if (btn == mainPage.buttonsMas[i])
{
pos = i;
}
}
if (currentStage == 20)
{
if (pos == sequence[currentMember])
{
SetColor();
ClearVariables();
stage = currentStage;
currentStage = 1;
return true;
}
ClearVariables();
stage = currentStage - 1;
currentStage = 1;
return false;
}
if (currentStage - currentMember == 1)
{
if (pos == sequence[currentMember])
{
SetColor();
ClearVariables();
stage = currentStage++;
return true;
}
ClearVariables();
stage = currentStage - 1;
currentStage = 1;
return false;
}
if (pos == sequence[currentMember])
{
currentMember++;
stage = currentStage;
return true;
}
else
{
ClearVariables();
stage = currentStage - 1;
currentStage = 1;
return false;
}
}
private void SetColor()
{
mainPage.Resources[string.Format("{0}", sequence[currentMember])] = colors[currentMember];
Thread.Sleep(1000);
mainPage.Resources[string.Format("{0}", sequence[currentMember])] = Color.LightGray;
}
private void ClearVariables()
{
currentMember = 0;
sequence = null;
colors = null;
}
}
}
MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="JustRepeat.MainPage">
<ContentPage.Resources>
<ResourceDictionary>
<Color x:Key="1">LightGray</Color>
<Color x:Key="2">LightGray</Color>
<Color x:Key="3">LightGray</Color>
<Color x:Key="4">LightGray</Color>
<Color x:Key="5">LightGray</Color>
<Color x:Key="6">LightGray</Color>
<Color x:Key="7">LightGray</Color>
<Color x:Key="8">LightGray</Color>
<Color x:Key="9">LightGray</Color>
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout>
<Grid VerticalOptions="FillAndExpand" >
<Button BackgroundColor="{DynamicResource Key=1}" Clicked="Buttons_Clicked" Grid.Column="0" Grid.Row="0" x:Name="one"/>
<Button BackgroundColor="{DynamicResource Key=2}" Clicked="Buttons_Clicked" Grid.Column="1" Grid.Row="0" x:Name="two"/>
<Button BackgroundColor="{DynamicResource Key=3}" Clicked="Buttons_Clicked" Grid.Column="2" Grid.Row="0" x:Name="three"/>
<Button BackgroundColor="{DynamicResource Key=4}" Clicked="Buttons_Clicked" Grid.Column="0" Grid.Row="1" x:Name="four"/>
<Button BackgroundColor="{DynamicResource Key=5}" Clicked="Buttons_Clicked" Grid.Column="1" Grid.Row="1" x:Name="five"/>
<Button BackgroundColor="{DynamicResource Key=6}" Clicked="Buttons_Clicked" Grid.Column="2" Grid.Row="1" x:Name="six"/>
<Button BackgroundColor="{DynamicResource Key=7}" Clicked="Buttons_Clicked" Grid.Column="0" Grid.Row="2" x:Name="seven"/>
<Button BackgroundColor="{DynamicResource Key=8}" Clicked="Buttons_Clicked" Grid.Column="1" Grid.Row="2" x:Name="eight"/>
<Button BackgroundColor="{DynamicResource Key=9}" Clicked="Buttons_Clicked" Grid.Column="2" Grid.Row="2" x:Name="nine"/>
</Grid>
<Button BackgroundColor="DarkGray" Text="Старт" Clicked="Button_Clicked" VerticalOptions="Fill" x:Name="startstop"/>
</StackLayout>
</ContentPage>
Trying to do "anything" like setting the color of a button to displaying an error in xamarin needs to be done in the correct place in the correct way. In your code setting the color of the buttons is irrelevant to your Application because you do not invoke the changes.
Setting the color with:
Device.BeginInvokeOnMainThread(() =>
{
// Your method to change the color.
button.BackgroundColor = Color.Black; // Or whatever.
});
If you need a DisplayAlert for example you can do this async too.
Device.BeginInvokeOnMainThread(async () => // <-----
{
// You await the message
await DisplayAlert("Attention", "Color changed!", "OK);
});
Resolved this to the comments, but i posted an answer for future reference.
Changing the value of a resource AFTER the page has been loaded won't affect the button color - it has already been read from the resource.
Instead, give the button an x:Name, so you can set its background color directly.
xaml:
<Button x:Name="button1" ... />
cs:
button1.BackgroundColor = ...;
OR might Device.BeginInvokeOnMainThread, as shown in stersym's answer.
(I added a new answer because that answer did not show x:Name.)
IMPORTANT: Intellisense won't know about button1 until after you build. What I do is add x:Name to XAML, build project, then add cs code that uses the name.
My Situation:
I'm trying to affect a label from one TabItem of a TabControl by clicking a Button on another TabItem of the same TabControl.
I'm currently having a hard time figuring out why the property of my TextBox textBoxTyp won't change its value even after updating the property. The binding is correct an a button right next to the TextBox (on the same TabItem) that's bound exactly like the other Button from the other `Tabitem, works perfectly fine. I'm using the MVVM pattern and databinding.
Here the code of the TabControl itself
<TabControl Name="TabSpaces"
SelectedIndex="{Binding TabIndex, Mode=TwoWay, Source={StaticResource vm_Für_Typenschild}}"
Background="White" Margin="0,0,0,-4">
<TabItem DataContext="{Binding TypneschildVM, Source={StaticResource vm_Für_Typenschild}}"
FontSize="15" Foreground="White" FontWeight="Bold" Background="#401746"
Header="Datei" Margin="0,0,-60,0">
<view:DateiV/>
</TabItem>
<TabItem MouseLeftButtonDown="SelectedTypenschild" Loaded="Typenschild_Loaded"
FontSize="15" Height="50" Foreground="White" FontWeight="Bold"
Background="#401746" Header="Typenschild" BorderBrush="#FFACACAC"
Margin="56,0,-128,0">
<view:TypenschildVM Width="Auto" Height="Auto" HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch" Margin="1,0"/>
</TabItem>
</TabControl>
Here the code from the view of the TabItem with the button that should affect the TextBox
<Button Command="{Binding ReadXmlAndInsertIntoDialogsIntoTypenSchild_Command, Source={StaticResource vm_Für_Typenschild}}"
FontSize="25" x:Name="button_Datei_entfernen" Foreground="White"
Content="Datei entfernen" HorizontalAlignment="Center" Margin="476,468,476,215"
VerticalAlignment="Center" Width="326" Height="70">
</Button>
Here the code from the functions that should change the property ( ReadXmlAndInsertIntoDialogsIntoTypenSchild & CompareXmlWithJsonAndInsertIntoDialog )
namespace WPF_App_RFID_SpinOff.ViewModel
{
public class TypneschildVM : INotifyPropertyChanged, ICommand
{
private string CompareXmlWithJsonAndInsertIntoDialog(string XmlFileStringToCheck, string IdFromJsonFile)
{
string ValueTopass = "";
string line = "";
StringReader StringReaderOfXmlFile = new StringReader(XmlFileStringToCheck);
while ((line = StringReaderOfXmlFile.ReadLine()) != null)
{
if (line.Contains(IdFromJsonFile) == true)
{
int IndexRightNow = line.IndexOf('V');
int IndexWhereValueStart = line.IndexOf('V');
int CounterToGetValue = 0;
for (CounterToGetValue = IndexWhereValueStart + 1; CounterToGetValue < line.Length; CounterToGetValue++)
{
if (line[CounterToGetValue] != '"' && line[CounterToGetValue] != '=' && line[CounterToGetValue] != '/' && line[CounterToGetValue] != '>')
{
ValueTopass += line[CounterToGetValue];
}
}
}
}
return ValueTopass;
// Console.WriteLine(TypenschildM_ToUse.Hardwareversion);
}
public void ReadXmlAndInsertIntoDialogsIntoTypenSchild(object parameter)
{
int OpenBracketCount = 0;
string IdFromJsonFile = "";
string StringOfJsonFile = StaticFunc.ProvideJsonFile();
string StringOfXmlFile = StaticFunc.ProvideXMLFile();
string StringOfInformationforTypenschildFromXml = GetPartOfXmlFileForTypenSchild(StringOfXmlFile);
string StringOfInformationforTypenschildFromJson = GetPartOfJsonFileForTypenSchild(StringOfJsonFile);
string BlockOfDataforCertainValue = " ";
Console.WriteLine("test");
foreach (char character in StringOfJsonFile)
{
if (character == '{')
{
OpenBracketCount++;
}
if (OpenBracketCount >= 1)
{
BlockOfDataforCertainValue += character;
if (character == '}')
{
Console.WriteLine(BlockOfDataforCertainValue);
IdFromJsonFile = lookOutForID(BlockOfDataforCertainValue);
PropTest = CompareXmlWithJsonAndInsertIntoDialog(StringOfXmlFile, IdFromJsonFile);
OnPropertyChanged("PropTest");
}
}
}
}
#region ICommandSchnittstelle
public bool CanExecute(object parameter)
{
throw new NotImplementedException();
}
public void Execute(object parameter)
{
throw new NotImplementedException();
}
#endregion
public TypneschildVM()
{
TypenschildM TypenschildM_ToUse = TypenschildM.Instance;
LeseXMLAus = new RelayCommand(ReadXMLFileForTypenschildVM, StaticFunc.enableExecute);
ReadXmlAndInsertIntoDialogsIntoTypenSchild_Command = new RelayCommand(ReadXmlAndInsertIntoDialogsIntoTypenSchild, StaticFunc.enableExecute);
startButtoon_Command = new RelayCommand(ReadXmlAndInsertIntoDialogsIntoTypenSchild, StaticFunc.enableExecute);
}
}
}
Heres The Binding of my Textbox
<TextBox IsReadOnly="True"
Text="{Binding PropTest, Source={StaticResource vm_Für_Typenschild}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
x:Name="textBoxTyp" Height="22" Margin="243,93,133,0" TextWrapping="Wrap"
VerticalAlignment="Top" Background="#FFF3F3F3" Grid.Column="2"/>
I created a editable ComboBox for searching(filtering) like Google. I am using the ActionHandler "KeyUp" and the first input is highlighted and overwritten. How can i disable the overwriting or highlighting?
private void CbInKuLi_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
{
CollectionView itemsViewOriginal = (CollectionView)CollectionViewSource.GetDefaultView(cbInKuLi.ItemsSource);
itemsViewOriginal.Filter = ((o) =>
{
if (String.IsNullOrEmpty(cbInKuLi.Text)) return true;
else
{
DeKreditor x = (DeKreditor)o;
string filterText = cbInKuLi.Text;
if (x.Nummer.ToLowerInvariant().Contains(filterText)
|| (!string.IsNullOrWhiteSpace(x.Firma) && x.Firma.ToLowerInvariant().Contains(filterText))
|| (!string.IsNullOrWhiteSpace(x.Vorname) && x.Vorname.ToLowerInvariant().Contains(filterText))
|| (!string.IsNullOrWhiteSpace(x.Name) && x.Name.ToLowerInvariant().Contains(filterText)))
return true;
else
return false;
}
});
itemsViewOriginal.Refresh();
cbInKuLi.IsDropDownOpen = true;
}
XAML:
<ComboBox
x:Name="cbInKuLi"
StaysOpenOnEdit="True"
IsEditable="True"
IsTextSearchEnabled="False"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Grid.Row="0"
Grid.Column="1"
Margin="5,0,5,5"
SelectionChanged="CbInKuLi_SelectionChanged"
KeyUp="CbInKuLi_KeyUp"
TextOptions.TextFormattingMode="Ideal" />
The Text Highlight caused because of setting IsDropDownOpen to true.
The Editable ComboBox auto select the Text if it is Opened, so you could get the TextBox from the template of the ComboBox by its Name than set the selection length to zero at the end of the text.
private void CbInKuLi_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
{
CollectionView itemsViewOriginal = (CollectionView)CollectionViewSource.GetDefaultView(cbInKuLi.ItemsSource);
itemsViewOriginal.Filter = ((o) =>
{
if (String.IsNullOrEmpty(cbInKuLi.Text)) return true;
else
{
Model x = (Model)o;
string filterText = cbInKuLi.Text;
if (x.Text.ToLowerInvariant().Contains(filterText))
return true;
else
return false;
}
});
itemsViewOriginal.Refresh();
cbInKuLi.IsDropDownOpen = true;
var textbox = (TextBox)cbInKuLi.Template.FindName("PART_EditableTextBox", cbInKuLi);
textbox.Select(textbox.Text.Length, textbox.Text.Length);
}
UPDATE:
From comments you can replace the last line by the following line and it is better than the original one:
textbox.CaretIndex = textbox.Text.Length;
I develop a game on Windows Universal App in C#. I have on my interface four buttons (left, right, up, down) to move the character on my map.
My question is : how to activate my function Move() with the keyboard arrows too ?
I tried a lot of solution from the web to get keys are pressed but most oh them concern only input forms...
You can use KeyDown to get the keyboard active.
The xaml is
<Page
x:Class="ktbkwbconcern.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:ktbkwbconcern"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" KeyDown="Grid_OnKeyDown">
<Button x:Name="btn" Content="K">
<Button.RenderTransform>
<CompositeTransform></CompositeTransform>
</Button.RenderTransform>
</Button>
<Grid VerticalAlignment="Bottom">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0" Content="left" Click="Button_OnClick"></Button>
<Button Grid.Row="1" Grid.Column="0" Content="up" Click="Button_OnClick"></Button>
<Button Grid.Row="0" Grid.Column="1" Content="down" Click="Button_OnClick"></Button>
<Button Grid.Row="1" Grid.Column="1" Content="right" Click="Button_OnClick"></Button>
</Grid>
</Grid>
</Page>
It will move the btn use button up and down.
And you should write code :
private void Grid_OnKeyDown(object sender, KeyRoutedEventArgs e)
{
if (e.Key == VirtualKey.Left)
{
Move(-1, 0);
}
else if (e.Key == VirtualKey.Right)
{
Move(1, 0);
}
else if (e.Key == VirtualKey.Up)
{
Move(0, -1);
}
else if (e.Key == VirtualKey.Down)
{
Move(0, 1);
}
}
private void Move(int x, int y)
{
var temp = btn.RenderTransform as CompositeTransform;
temp.TranslateX += x;
temp.TranslateY += y;
}
private void Button_OnClick(object sender, RoutedEventArgs e)
{
var b = sender as Button;
if (b != null)
{
string str = b.Content as string;
if (str == "up")
{
Move(0, -1);
}
else if (str == "down")
{
Move(0, 1);
}
else if (str == "left")
{
Move(-1, 0);
}
else if (str == "right")
{
Move(1, 0);
}
}
}
}
You should use the Grid.KeyDown to get the key and make btn to move.
If have no notion of the code ,please talk me.
i've defined an initial Table with three rows and 9 Column in Datagrid. right now button should be visible only if i select a row and then press another button that i defined in my Ribbon-Tab after that my Button will be Visible. sofar everything works well, but the Problem is after saving my Table, closing it and open the Table again the button is not there anymore. I set the Visibility based on if the DataGridCell.IsSelected, also a BooleanToVisibilityConverter to convert the boolean value to a Visibility one.
can anyone help!
XAML:
<DataGrid.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVisConverter" />
</DataGrid.Resources>
<DataGridTemplateColumn x:Name="subgraphtyp" Header="H." Width="50">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Name="btnTable" Visibility="{Binding Path=Hinterlegung, Converter=
{StaticResource BoolToVisConverter}}" Height="20" Width="25"
Click="Button_Table_Click">
<Image Height="16" Source="Subgraph.png" Stretch="Fill" Width="16"/>
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
C#:
public bool Hinterlegung { get; set; }
private void Button_StartTableModus(object sender, RoutedEventArgs e)
{
if (DataGrid1.SelectedItem != null && tabItem1.IsSelected)
{
TableDataRowStringItem item = (TableDataRowStringItem)DataGrid1.CurrentItem;
string wert = item.ObjectType;
string rowName = item.Name;
if (wert == "Function" || wert == "Process")
{
item.Hinterlegung = true;
if (!tabControl.Items.Contains(tabItem2))
{
tabControl.Items.Add(tabItem2);
tabItem2.Focus();
tabItem2.IsSelected = true;
tabItem2.Header = rowName;
TableTab.Visibility = Visibility.Visible;
openTabs++;
DataGrid2.IsReadOnly = false;
starting_Table_Mod_at_start2V();
}
}
}
}
//this my initial Table
private ObservableCollection<TableDataRowStringItem> tableobject = new
ObservableCollection<TableDataRowStringItem>();
private void starting_Table_Mod_at_start2V()
{
List<TableDataRowStringItem> rowstringList = new List<TableDataRowStringItem>();
TableDataRowStringItem item = new TableDataRowStringItem();
item.RowNumber = 1; item.saveFlag = true; item.ObjectType = "E"; item.Name = "E";
item.PredecessorRowNumber = "0"; rowstringList.Add(item);
item = new TableDataRowStringItem();
item.RowNumber = 2; item.ObjectType = "Function"; item.Name = "Function";
item.PredecessorRowNumber = "1"; rowstringList.Add(item);
item = new TableDataRowStringItem();
item.RowNumber = 3; item.ObjectType = "E"; item.Name = "E";
item.PredecessorRowNumber = "2"; rowstringList.Add(item);
for (int i = 0; i < rowstringList.Count; i++)
{
tableobject.Add(rowstringList[i]);
}
DataGrid2.ItemsSource = tableobject;
}
Your button's visibility is bound to your Hinterlegung variable which has a default value of false. So as best as I can tell, you change it to true in this method - Button_StartTableModus. But, when you reinitialize, the value reverts to false, so you need to set it to true.