Select ComboBox Text - c#

I have a ComboBox declared as follows:
<ComboBox Name="txtUserName" IsEditable="True" />
I want to select the ComboBox's text field on focus, but I can't figure out how to do this. Currently, when the ComboBox is focused on programmatically (through "txtUserName.Focus()"), it allows the user to scroll through the different items, but requires an additional click to highlight the text field.
Any thoughts?

The solution I used was to add the following code to the window's loaded event:
var textBox = (txtUserName.Template.FindName("PART_EditableTextBox", txtUserName) as TextBox);
if (textBox != null)
{
textBox.Focus();
textBox.SelectionStart = textBox.Text.Length;
}
The solution came from one of the suggested answers here: How to add a focus to an editable ComboBox in WPF

Try this:
if (txtUserName.Items.Count > 0)
{
txtUserName.SelectedIndex = 0;
}
Also, you may want to use a different prefix, like "cbo".
Other readers of the code will assume it is a textbox, not a combobox.

Try add comboBox template like this:
<ComboBox Name="txtUserName" IsEditable="True">
<ComboBox.Template>
<ControlTemplate>
<TextBox Text="{Binding Path=/*your property*/}"/>
</ControlTemplate>
</ComboBox.Template>
</ComboBox>

Related

TabControl SelectedContent not returning the current selected TabItem content

Currently I have a TabControl with several TabItems. Each TabItem has a DataGrid inside. I wanted to format these DataGrids (cell colors, column widths, etc) all at once but I found I can't because all the DataGrids from the hidden tabs would return null properties. In this case, I tried to make a work around where I would select programmatically (or manually with the mouse) the tabs before formatting the DataGrid. But now I'm up against a "strange" behavior:
private void LeftTabs_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Console.WriteLine(LeftTabs.SelectedIndex);
var currentDataGrid = (DataGrid)LeftTabs.SelectedContent;
Console.WriteLine(currentDataGrid.Name);
}
The selected index returns the correct tab index, but the content it's not updated.
Let's say Tab 1 is selected and then I click on Tab 2. It returns me the Tab 2 index and the Tab 1 DataGrid name.
This behavior prevents me from editing the select tab's DataGrid because even if I try to access it directly by it's object, all the properties return null.
This is the TabControl, item and DataGrids XAML code:
<TabControl Name="LeftTabs" Margin="0,0,0,0" Grid.Column="0" Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" SelectionChanged="LeftTabs_SelectionChanged">
<TabItem>
<TabItem.Header>Conditions</TabItem.Header>
<DataGrid x:Name="DataGrid_Conditions" SelectedCellsChanged="DataGrid_Conditions_SelectedCellsChanged" ColumnWidth="80" ItemsSource="{Binding}" HorizontalAlignment="Stretch" VerticalAlignment="Top" SelectionChanged="ConditionsSelected" />
</TabItem>
<TabItem>
<TabItem.Header>Signals</TabItem.Header>
<DataGrid x:Name="DataGrid_Signals" ColumnWidth="80" ItemsSource="{Binding}" HorizontalAlignment="Stretch" VerticalAlignment="Top" SelectionChanged="SignalsSelected" />
</TabItem>
</TabControl>
EDIT:
To be more clear I'll minimize the scenario.
TabItem1 - Has DataGrid_Conditions inside;
TabItem2 - Has DataGrid_Signals inside.
Here is another code that I try to run when I manually or programmatically select a tab:
DataGridRow Row = (DataGridRow)DataGrid_Signals.ItemContainerGenerator.ContainerFromIndex(ID);
What happens is, If I click on tab2 this code doesn't for tab2's Grid. Instead it works for the previous tab(1) Grid.
The LeftTabs.SelectedContent is the only property not being updated.
I can't seem to reproduce your issue. "DataGrid_Signals" should be printed out when you selecte the second tab. You may also get a reference to the currently selected TabItem from the SelectionChangedEventArgs:
private void LeftTabs_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Debug.WriteLine(LeftTabs.SelectedIndex);
TabItem tabItem = e.AddedItems[0] as TabItem;
var currentDataGrid = (DataGrid)tabItem.Content;
Debug.WriteLine(currentDataGrid.Name);
}
In this example despite it indeed printing "DataGrid_Signals" when I try to get anything from the grid's object, it just comes null as it was in a hidden.
This is because it has not yet been loaded. You can force it to render by measure and arrange it:
private void LeftTabs_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (IsLoaded)
{
TabItem tabItem = e.AddedItems[0] as TabItem;
var currentDataGrid = (DataGrid)tabItem.Content;
currentDataGrid.Measure(new Size(currentDataGrid.ActualWidth, currentDataGrid.ActualHeight));
currentDataGrid.Arrange(new Rect(0, 0, currentDataGrid.ActualWidth, currentDataGrid.ActualHeight));
//...
}
}
This is a bug, fixed in .NET 4.7.1 but quirked so that apps targeting 4.7 or below still get the old behavior. See the breaking change announcement for details.

Working with elements inside a control that is bound to a collection

I have an ObservableCollection<string> that is bound to an ItemsControl whose template is just a Button. The content of this button are 2 TextBlock. I'm trying to use the PreviewMouseRightButtonUp event of the button to toggle the visibility of one of the textblocks, but without being able to use xaml names for elements in the template I'm hitting a wall. Is there a way of getting to the button's content elements via sender in that preview event, or some other way of doing this? This is related to a previous question I had that didn't quite get a usable answer (probably due to my explanation, hence this simplified example). It seems to me that what should happen is I should make a control based off button that adds a property for this toggle, but that is basically what I thought I had in the previous question that wasn't working. I feel like a property and trigger is what most would say is the right way to go?
xaml:
<ItemsControl x:Name="iC" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button PreviewMouseRightButtonUp="Button_PreviewMouseRightButtonUp">
<DockPanel>
<TextBlock Text="normal" DockPanel.Dock="Top"/>
<TextBlock Text="{Binding}" DockPanel.Dock="Top" Visibility="Collapsed"/>
</DockPanel>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
code behind:
ObservableCollection<string> x = new ObservableCollection<string>();
public MainWindow()
{
x.Add("1");
x.Add("2");
InitializeComponent();
iC.ItemsSource = x;
}
If you name the hidden text block "secondTextBlock", then this should work:
private void Button_PreviewMouseRightButtonUp(object sender, MouseButtonEventArgs e)
{
DockPanel dockPanel = (DockPanel)((Button)sender).Content;
TextBlock text = (TextBlock)LogicalTreeHelper.FindLogicalNode(dockPanel, "secondTextBlock");
if (text != null)
{
text.Visibility = Visibility.Visible;
}
}
Regarding your comment below: yes, multiple instances of "secondTextBlock" will be created. See the Snoop screenshot below. But these multiple instances are OK; they do not have any negative impact.

Disable the drop down menu of a WPF ComboBox

I have a ComboBox as specified below:
<ComboBox Height="31" Margin="7,7,0,0" Name="callerID" IsEditable="True" Background="LightBlue" KeyDown="callerIDbar_KeyDown" Foreground="White" FontSize="17" FontWeight="Bold" HorizontalContentAlignment="Center" VerticalAlignment="Top" Grid.Row="0" Grid.Column="0" />
storedCalls is a collection of phone numbers that will be populated to the ComboBox.Items:
foreach (string call in storedCalls)
{
if (call != "Enter a number to dial")
callerID.Items.Add(call);
}
All this works fine. I populate the Items primary because I like the autocomplete that is driven by the values in the ComboBox's Items collections. Is there a way the XAML to disable the drop down error, and disable the drop down menu? I.e. make a simple auto complete textbox like control?
I have seen full on TextBox controls that include a bunch of code-behind and complicated markup, and this is not what I am looking to do. I just need to disable the ability of the drop down menu from showing.
You can handle the DropDownOpened event and then close it.
So in n the XAML you get:
<ComboBox x:Name="cb" DropDownOpened="cb_DropDownOpened"/>
And in Code Behind:
private void cbCategoria_DropDownOpened(object sender, EventArgs e)
{
ComboBox cb = sender as ComboBox;
cb.IsDropDownOpen = false;
}
I prefear this solution reather than set MaxDropDownHeight to 0.
Your choice.

GridView Row Does not get select or Affected When Checkbox checked on Grid

I am using WPF Application Form with Telerik Gridview using C#.
In that Gridview i inserted checkboxes using Data template.
Its created but when i click or check the checkbox the current row is not getting selected.
How can i solve this problem?
Please anyone tell me the solution of this problem.
My xaml code for creating checkbox in grid is:
<telerik:GridViewDataColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
<CheckBox Name="CheckBox" IsChecked="{Binding IsSelected,UpdateSourceTrigger=PropertyChanged}" Click="CheckBox_Click" />
</StackPanel>
</DataTemplate>
</telerik:GridViewDataColumn.CellTemplate>
In that checkbox i have created click event.
And also i want to know the current row number of the CheckBox Placed row in the gridview in checkbox click event. Give me some suggestion for this.
Here My CheckBox Click event Code:
private void CheckBox_Click(object sender, RoutedEventArgs e)
{
CheckBox selectedCheckbox = (CheckBox)sender;
//this.selectedCasePackRadGrid -- This is my gridview
// Here I want to get the selected row number
}
Thanks in Advance.
First of all, I don't see you actually setting the row as Selected anywhere.
Your binding currently is setting a property in your DataContext called IsSelected. If this property actually exists, you can bind it to GridViewRow.IsSelected in a style
<Style TargetType="{x:Type telerik:GridViewRow}">
<Setter Property="IsSelected" Value="{Binding IsSelected}" />
</Style>
If it doesn't exist in your data object, you need to use a RelativeSource binding to find the GridViewRow and bind to it's IsSelected property
Checked="{Binding RelativeSource={RelativeSource AncestorType={x:Type telerik:GridViewRow}}, Path=IsSelected}"
As for finding the row number, there is no RowIndex property I know of that you can use to find the row number. One alternative is to get the GridView's ItemsSource and call IndexOf(dataobject), however that does break the separation of MVVM layers
private void CheckBox_Click(object sender, RoutedEventArgs e)
{
CheckBox checkBox = (CheckBox)sender;
var dataItem = checkBox.DataContext as MyDataItem;
var parentDataObject = myGridView.ItemsSource as SomeDataObject;
if (dataItem == null || parentDataObject == null)
return;
var index = parentDataObject.SomeCollection.IndexOf(dataItem);
// Do something with index
}
There are also other alternatives such as setting AlternationCount to something higher than the the number of rows, and accessing GridViewRow.AlternationIndex, although I don't know if that will work with Telerik's GridView
But perhaps the best thing you could do is evaluate what you actually need the index for, and see if you can use some other alternative to accomplish what you want. For example, if you want to pass the index of the selected row to a button command, it would be better to just pass the SelectedItem as the CommandParameter.

Binding Text Property in Autocomplete Combobox

could someone help me to solve an issue with combobox behaviour. Here is my combobox control (WPF):
<ComboBox Grid.Row="1" Grid.Column="1" Margin="6,0,6,6" Name="comboBoxRegionTown" IsEditable="True" IsTextSearchEnabled="True" PreviewKeyUp="comboBoxRegionTown_PreviewKeyUp" IsTextSearchCaseSensitive="False" />
The idea is to make it autocomplete (IsEditable="True" IsTextSearchEnabled="True"). So then I typу any text into combobox it shows some results from database.
Here is a code of comboBoxRegionTown_PreviewKeyUp event (C#):
private void comboBoxRegionTown_PreviewKeyUp(object sender, System.Windows.Input.KeyEventArgs e)
{
if (!string.IsNullOrEmpty(comboBoxRegionTown.Text))
{
comboBoxRegionTown.ItemsSource = _br.GetQuery(x => x.Name.Contains(comboBoxRegionTown.Text) && x.RegionTypeId == (int)RegionType.Town).ToList();
comboBoxRegionTown.IsDropDownOpen = true;
}
else
{
comboBoxRegionTown.ItemsSource = null;
}
}
So that works fine for me, but then I click to any found item in combobox it puts into ComboBox.Text property the type of my selected object (in this case - Region). Of course I can override ToString() method for my Region object and set there its public property Name and this solution works fine, but I think the best way is to find how to bind selected item into Text property of my combobox. Is there any way to do this?
I've already tryed to ind Text="{Binding Path=Name}" and/or SelectedItem="{Binding Path=Name}" but in these cases just always get empty Text. Please help.
What you need to do is set the ItemTemplate for your ComboBox, but if you just want to display a single property there's an easier way: set DisplayMemberPath="Name" in the ComboBox and it'll generate the correct template for you.

Categories