I have a Silverlight application with a ComboBox that is filled by VideoCaptureDevice's.
cbVideoDevices.ItemsSource = CaptureDeviceConfiguration.GetAvailableVideoCaptureDevices();
I'm trying to add item, "Select a video device" to the first index but I can't get it to work.
XAML Code:
<ComboBox Height="25" HorizontalAlignment="Left" Margin="0,0,0,0" Name="cbVideoDevices" VerticalAlignment="Top" Width="125" ItemsSource="{Binding AudioDevices}" SelectedItem="{Binding SelectedAudioDevice}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding FriendlyName}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Your explicitly setting the ItemsSource in the code behind and the XAML, choose one or the other. Ideally you would take the XAML approach and set the DataContext appropriately.
Once you make that decision you can insert an item within your ComboBox by using the Items property.
ComboBox box = new ComboBox();
box.Items.Insert(0, "My Item");
A better approach would be to leverage the ICollectionView and simply sort the data and let the UI respond accordingly. Your ItemsSource would then be bound to the ICollectionView.
You can easily insert an item at a desired index location in the Items collection of the ComboBox using the following code.
TextBlock t = new TextBlock();
t.Text = "Select a video device"
combo.Items.Insert(0, t);
Setting the selected index will set the ComboBox to show your added item by default:
combo.SelectedIndex = 0;
or
you can do like this..
YourClassObject objSelectItem = new YourClassObject();
objSelectItem.ID = "0";
objSelectItem.Name = "Select Item";
ComboBox1.Items.Insert(0,objSelectItem);
i hope it will helps you...
Related
I'm currently making a transferring data from one listbox to another.
With WPF I have:
<Grid>
<ListBox Margin="10,29,194,301" Name="LeftListBox"/>
<ListBox Margin="0,29,16,301" Name="RightListBox" HorizontalAlignment="Right" Width="173" />
<Button Name="AddButton" Height="23" Margin="34,135,227,0" VerticalAlignment="Top"
Click="AddButton_Click">Add >></Button>
<Button Name="RemoveButton" Margin="227,135,34,264"
Click="RemoveButton_Click"><< Remove</Button>
</Grid>
For my C# code, I created two methods that loads the left box's elements by using an array of Strings and the right one's.
Now My issue is that I want an element of the left box to be placed into the right box after the last element of the right box's list. So when I click on add, it should execute this method:
private void AddButton_Click(object sender, RoutedEventArgs e)
{
// Find the right item and it's value and index
currentItemText = LeftListBox.SelectedValue.ToString();
currentItemIndex = LeftListBox.SelectedIndex;
ObservableCollection<string> oList;
oList = new System.Collections.ObjectModel.ObservableCollection<string>(toRemoveList);
RightListBox.DataContext = oList;
Binding binding = new Binding();
RightListBox.SetBinding(ListBox.ItemsSourceProperty, binding);
(RightListBox.ItemsSource as ObservableCollection<string>).Add(currentItemText);
if (toAddList != null)
{
toAddList.RemoveAt(currentItemIndex);
}
// Refresh data binding
ApplyDataBinding();
}
But the problem is that when I select an item from the left box, then click on add, it adds the new item into the right box but when I add a second item, it replaces the last one item that I added at the first step.
After that, the second problem is, how would be implemented the RemoveButton_Click ? Is it the same way as the previous method ?
You need not to do this much of code for this. Follow below given steps for more robust and maintainable approach.
Create two Observablecollection corresponding to left and right ListBox
Bind Observablecollection to ListBox
On Add button click, remove the item from observable collection assigned to left listbox and add to the oberservable collection binded to right grid.
You need not to update the bindings explicitly. Observable collection notify the collection changes automatically.
In code -
public ObservableCollection<ApplicationFormats> Formats { get; set; }
Xaml -
<ListBox Name="LeftListBox" ItemsSource="{Binding Formats}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I have a custom control ListItem. I need to display five such items in a window and these items could change during runtime; items could be added or deleted, or content could change in ListItem.
ListBox appears to be a good solution to display items. But what I have seen is we can add items and style them, and can handle updates with data trigger.
myListBox.Items.Add(new { FileName = "SomeFile", State="Uploaded" });
But we can not do something like
ListItem curItem = new ListItem();
myListBox.Items.Add(new { curItem });
Even if I do it shows empty item in the list.
So if I want to add my custom control to some listbox, how could that be possible. That is using ListBox just as a container so we can get away from the pain of positioning and all that after list changes. Or is there a better way to do that?
You are in luck - this is the bread and butter of WPF! Set the ItemsSource of your ListBox (possible in XAML or cs):
myListBox.ItemsSource = myEnumerableCollection;
or
<ListBox ItemsSource="{Binding MyItemsProperty}">
Use a DataTemplate (you do not need a UserControl) to style each item in XAML:
<ListBox ItemsSource="{Binding MyItemsProperty}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding FileName}"/>
<TextBlock Text="{Binding State}"/>
<!--Whatever you want-->
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
If your collection is an ObservableCollection<T> changes to that collection (e.g. items added or removed) will be reflected in the ListBox automatically. If T implements INotifyPropertyChanged changes to properties on each item will also automatically show up on the UI.
For more see the WPF Binding Overview.
Don't create or manipulate UI elements in procedural code in WPF.
<ListBox ItemsSource="{Binding SomeCollection}">
<ListBox.ItemTemplate>
<DataTemplate>
<my:MyControl/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
where my:MyControl is a UserControl with whatever UI you want.
I have in the mainwindow this code:
<TabControl x:Name="tc" Margin="0" SelectedIndex="0">
<TabItem Header="Tab 1" Width="150"
IsSelected="false">
<!--<TextBox Width="200" Height="200"/>-->
</TabItem>
</TabControl>
i have a mainwindowviewmodel and i want it to bind to the controltab name which is tc:
private void AddTab_Execute(object parm)
{
s = s + 1;
TabItem Item = new TabItem();
Item.Width = 150;
Item.Header = "Tab " + s;
tc.Items.Add(Item);
}
he doesn't recognize tc
what do i have to do ?
This has nothing to do with binding, but it would be easier if you had one. You should not need to reference controls like the TabControl in the view-model.
Bind the ItemsSource of the the TabControl to an ObservableCollection, then you just need to add items to that collection. Use the ItemTemplate (header) and ContentTemplate (tab item content) to create the tabs from the items in the collecton dynamically.
First of all, be careful with how you are using the word "bind". That has a particular meaning which is not what you are doing in your example. To see what binding actually means, check out this article.
You cannot access controls in your UI from your viewmodel. What you should be doing is binding the ItemsSource of the TabControl to a collection in the viewmodel. You can create DataTemplateSelectors and use them for the TabControl's ContentTemplateSelector and ItemTemplateSelector if you want to select different templates depending on the item which is bound to each TabItem.
I am using the following code for binding ListBox to a list i.e. List and set the binding Path=Name. But the list box shows just the one name with letter divided in rows. Like if a Name is JOHN, the list box row 1 shows "J", row 2 shows "O", row 3 shows "H", row 4 shows "N". Here's the code.
Xaml
<ListBox Height="Auto" ItemsSource="{Binding Path=Name}" HorizontalAlignment="Stretch" Margin="0,80,0,0" Name="ledgerListView" VerticalAlignment="Stretch" Width="200" KeyDown="ledgerListView_KeyDown" MouseDoubleClick="ledgerListView_MouseDoubleClick" IsSynchronizedWithCurrentItem="True" />
Code-Behind
List<Ledgers> ledgers = new List<Ledgers>();
ledgers = DAL_Ledgers.LoadLedgers();
this.DataContext = ledgers;
The ItemsSource property needs to be bound to the source collection that you want to generate the list box's items from. In this case that would just be the DataContext. To show the name for each item you can either apply a DataTemplate to the ItemTemplate property containing what you want to show for each item, or for a simple case like this just use the DisplayMemberPath to specify the Name property.
<ListBox ItemsSource="{Binding}" DisplayMemberPath="Name" x:Name="ledgerListView"/>
It looks like you're binding to the wrong thing... Does it work if you use:
<ListBox ItemsSource="{Binding}" ...>
<ListBox.ItemTemplate>
<DataTemplate>
<sdk:Label Content="{Binding Path=Name}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Also, you might want to use an ObservableList, otherwise changes in ledgers won't be taken into account.
I have a List bound to a TreeView like:
XAML:
<TreeView Name="browserTree"
BorderBrush="DarkSlateGray"
BorderThickness="1"
Grid.Row="2"
Margin="0,3,0,0"
ItemsSource="{Binding UpdateSourceTrigger=PropertyChanged}">
<TreeView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</TreeView.ItemTemplate>
</TreeView>
C#:
browserTree.DataContext = treeList;
I update the list via:
void QueryChange(string s)
{
rCM.SetCommand(s);
treeList.Clear();
SqlDataReader sr = rCM.ExecuteReader(System.Data.CommandBehavior.Default);
while (sr.Read())
{
treeList.Add((string)sr["tree_hdr"]);
}
sr.Close();
}
The List<string> is just a placeholder at the moment for a more meaningful data class I have yet to implement. But right now I need to know why the TreeView is not updating to reflect the changes made to the list.
Try making the treelist an ObservableCollection.
Please check the type of your treeList which you set as DataContext. It has to be an ObservableCollection to reflect your collection changes in the UI
Or else for quick workaround, just set the DataContext again after you filled the List.