Getting Text from ComboBox in WPF - c#

I have a ComboBox in WPF and I cant access its selected item text.
I have tried
cbItem.Text;
cbItem.SelectedItem.ToString();
XAML:
<ComboBox Name="cbItem" SelectedValuePath="ITEM_ID">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding ITEM_NAME}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>

Do ITEM_ID and ITEM_NAME come from an object?
String textComboBox = ((ITEMCLASS)cbItem.SelectedItem).ITEM_NAME.ToString();

Try
cbItem.SelectedValue.ToString()
This will work only if combobox values are same as the combobox text
EDIT:
Solution 1
You have to get access to the ComboBox's TextBox:
var str = (TextBox)cbItem.Template.FindName("PART_EditableTextBox", cbItem);
Then you can access the SelectedText property of that TextBox:
var selectedText = str.SelectedText; // This will give you text of selected item
Solution 2
ComboBoxItem typeItem = (ComboBoxItem)cbItem.SelectedItem;
string value = typeItem.Content.ToString();// This will give you text of selected item

Try this
<ComboBox Name="cbItem" SelectedValuePath="ITEM_ID">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Name="txtblck" Text="{Binding ITEM_NAME}" />
</DataTemplate>
</ComboBox.ItemTemplate>
TextBox str = (TextBox)cbItem.FindName("txtblck");
string text = str.Text;

Related

WPF binding 2 properties from 1 List

So what i am trying to accomplish is that i am trying to bind 2 properties from 1 list to 2 different ComboBoxes.
code:
combobox1.DataContext = class.repository;
combobox2.DataContext = class.repository;
and in xaml
<ComboBox x:Name="combobox1" ItemsSource="{Binding Name}"/>
<ComboBox x:Name="combobox2" ItemsSource="{Binding Password}"/>
example - repository[0] = "NAME1"
The result i get is when i open ComboBox looks like:
1 item - N
2 item - A
3 item - M
and so on..
and result i want is
1 item = NAME1
2 item = NAME2
...
Thanks for replies.
If repository is a string[], you should bind the ItemsSource to the DataContext itself:
<ComboBox x:Name="combobox1" ItemsSource="{Binding}"/>
If repository is an IEnumerable<YourClass> where YourClass is a type with a Name and a Password property, you should also set the DisplayMemberPath property:
<ComboBox x:Name="combobox1" ItemsSource="{Binding}" DisplayMemberPath="Name" />
<ComboBox x:Name="combobox2" ItemsSource="{Binding}" DisplayMemberPath="Password"/>
You should use DisplayMemberPath property of the ComboBox to specify you want to see the value of propery "Name".

GetItemAt returning null value instead of ComboBoxItem

I have two ComboBox with same items.
I am trying to get the ComboBoxItem of a ComboBox by Index but NULL value is being returned.
My code is:
var index = comboBox1.SelectedIndex;
ComboBoxItem item = comboBox2.Items.GetItemAt(index) as ComboBoxItem; // item is null here
//item = (ComboBoxItem)comboBox2.ItemContainerGenerator.ContainerFromItem(comboBox1.SelectedItem);
//also tried above line but same result(null)
And XAML:
<ComboBox Name="comboBox1" ItemsSource="{Binding ExistingModuleGroups}" SelectedItem="{Binding SelectedModuleGroup}" SelectionChanged="ComboBox1_SelectionChanged">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<ComboBox Name="comboBox2" ItemsSource="{Binding ExistingModuleGroups}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
private void comboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count > 0)
{
if (comboBox2.Items.Count > 0)
{
var index = comboBox1.SelectedIndex;
ComboBoxItem item = comboBox2.Items.GetItemAt(index) as ComboBoxItem; // item is null here
//item.IsEnabled = false;
}
}
}
Any idea...
The ItemsControl.Items property stores the actual data, not the generated ComboBoxItems (unless you've manually added objects of type ComboBoxItem to the Items collection).
You were close with that second piece of code you've commented, but you were looking for an item from the first combo in the second combo. Since you are probably not using the same instances for both combos, that won't work.
The correct thing would probably be this. Similar to what you've already tried, but with some key differences:
var index = comboBox1.SelectedIndex; // Get the index from the first combo
var item = (ComboBoxItem)comboBox2.ItemContainerGenerator
.ContainerFromIndex(index); // And get the ComboBoxItem from that index
// in the second combo

XAML / C# Extracting data from a group of TextBox in a ListView?

I am creating a Windows phone 8.1 application
I have a generated a list of textboxes RepTb in a listview. But I cannot figure out a way to get the text in these textboxes.
<Grid>
<Grid.Resources>
<DataTemplate x:Name="items">
<TextBox Name="RepTb" Header="{Binding}"
Width="100" HorizontalAlignment="Left"
LostFocus="RepTb_LostFocus"/>
</DataTemplate>
</Grid.Resources>
<ListView x:Uid="RepListView"
ItemsSource="{Binding}"
ItemTemplate="{StaticResource items}"
Name="RepList"/>
</Grid>
Code used to create textboxes:
List<string> setlist = new List<string>();
int set = 10;
for (int i = 1; i <= set; i++ )
setlist.Add("Reps in Set " + i);
RepList.DataContext = setlist;
Can anyone tell me how to iterate through RepList and get the content off the textboxes?
You can use a TwoWay data binding to get value of your textbox.
First you need to create a class which will contain your data.
public class RepItem
{
public string Header {get; set;}
public string Value {get;set;}
}
Then inject a List instead of a List
List<RepItem> setlist = new List<RepItem>();
int set = 10;
for (int i = 1; i <= set; i++ )
setlist.Add(new RepItem() {Header = "Reps in Set " + i});
RepList.DataContext = setlist;
Finally, bind the TextBox Text property to Value property of your RepItem object :
<DataTemplate x:Name="items">
<TextBox Name="RepTb"
Header="{Binding Header}"
Text="{Binding Value, Mode=TwoWay}"
Width="100"
HorizontalAlignment="Left"
LostFocus="RepTb_LostFocus"/>
</DataTemplate>
You can use Text="{Binding Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" if you want that the Value property is updated each time you type a character, otherwise it will be updated when hte focus on the TextBox is lost.
You will be able to iterate through your List and get all the values
((List<RepItem>)RepList.DataContext).Select(repItem => repItem.Value);

Datagrid ComboBox binding two values

I have a combobox which is populated from a list of names which were obtained from selecting from an Observable collection. However, associated with those names is an ID also in that Observable collection. The goal is when the user selects a new name (Say changes "John" to "Jill") I will be able to obtain the ID, not just the name. The only way I can think of doing this is storing the ID also in the combobox somehow. But I don't know how to do that with binding.
<DataGridTemplateColumn Header="Name ">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox x:Name="namescombo" ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=DataContext.Names}"
SelectedItem="{Binding Name, UpdateSourceTrigger=PropertyChanged}" FontSize="12" Background="White" FontFamily="Cambria" BorderBrush="White" BorderThickness="0"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
C#
ObservableCollection<Name> Names = new ObservableCollection<Name>();
Name twofields = new Name();
var NamesQuery =
from p in dataEntities.Names
select new { p.Name, p.Id };
foreach (var p in NamesQuery)
{
Names.Add(new Name
{
ID = p.Id,
Name = p.Name
});
}
Names = Names.Select(p => p.Name).Distinct().ToList();
A ComboBox contains properties for both the DisplayMemberPath and the SelectedValuePath, so you could use it to tell the ComboBox to identify items by the "Id" property, but display the "Name" property to the user.
For example,
<DataGridTemplateColumn Header="Name ">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=DataContext.Names}"
DisplayMemberPath="Name"
SelectedValuePath="Id"
SelectedValue="{Binding SelectedId}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
I would recommend using SelectedValue over SelectedItem because WPF compares SelectedItem by .Equals() which defaults to comparing items by reference, and if your SelectedItem is not the exact same reference as the item in your ItemsSource, it won't get selected.
For example, SelectedItem = new Person(1, "Test"); would probably not set the selected item correctly, while SelectedItem = ItemsSource[0] would since it refers to an item that exists in the ItemsSource.
Also, it frequently makes more sense to store just the Id of the selected item on a row instead of the entire object :)
You can bind directly to Name object collection and set DisplayMemberPath to Name property so that strings are shown on GUI but in essence you have complete object binded to comboBox.
This way you can bind SelectedItem to Name object and can access Id and Name property.
<ComboBox ItemsSource="{Binding Names}" // Collection of name objects.
DisplayMemberPath="Name"
SelectedItem="{Binding SelectedNameObject}"/> // Object of type Name.

how to Remove item from one Listbox and add into another Listbox?

I am trying to remove selected item from one listbox and add that into new listbox as follows code
Binding on PageLoad:
Getting the records from database into a DataTable and bind that to Listbox.
lstBox1.DataContext = dtData;
Code Bind:
List<object> _selecteditems = new List<object>();
foreach (var item in lstBox1.SelectedItems)
{
_selecteditems.Add(item);
}
foreach (var item in _selecteditems)
{
lstBox1.Items.Remove(item);
lstBox2.Items.Add(item);
}
Design:
<ListBox Name="lstBox1" ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding ID}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox Name="lstBox2" ItemsSource="{Binding}" >
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding ID}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I am getting an error when removeing the item "Operation is not valid while ItemsSource is in use. Access and modify elements with ItemsControl.ItemsSource instead."
Don't manipulate the items via the Items property, instead add/remove items from the List that the ListBox is bound to:
<ListBox Name="lstBox1" ItemsSource="{Binding myListProperty}">
...etc...
</ListBox>
If your myListProperty returns a collection that implements INotifyCollectionChanged (like the ObservableCollection does) then the listboxes will automatically show the new items as they are added and the removed items will instantly disappear.
I tried by following way and its working for me.
List<object> _selecteditems = new List<object>();
foreach (var item in lstBox1.SelectedItems)
{
_selecteditems.Add(item);
}
foreach (var item in _selecteditems)
{
DataRow dr = dtSelctedDest.NewRow();
dr[0] = ((DataRowView)item).Row[0].ToString();
dr[1] = ((DataRowView)item).Row[1].ToString();
dtSelctedItem.Rows.Add(dr);
dtAllItem.Rows.Remove(dtAllItem.Rows.Remove.Select(string.Format("ID='{0}'", ((DataRowView)item).Row[0].ToString()))[0]);
}
lstBox1.DataContext = dtAllItem;
lstBox2.DataContext = dtSelctedItem;

Categories

Resources