Wpf ListBox with text and images - wpf

I need to create an ordering list having as elements strings and images (some items are text, other -images). I have to configure this list from code behind, not in xaml.
I created a class :
public class SimpleChoicePair
{
public SimpleChoice Choice { get; set; }
public FrameworkElement Content { get; set; }
}
where as Content I have TextBlock or Image objects. My listbox looks like:
var listboxChoices = new ListBox();
var list = new ObservableCollection();
listboxChoices.DisplayMemberPath = "Content";
listboxChoices.ItemsSource = choicesList;
But the items in the list display only the class name of TextBlock or Image. How can I display the uiElements themselves? Thanks for any help

If i am right you are looking about the itemtemplateselector on the basis of your content for e.g if content type text then show the textbock or if its image type then show me the images. see below exampbles.
http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.itemtemplateselector.aspx
http://www.switchonthecode.com/tutorials/wpf-tutorial-how-to-use-a-datatemplateselector

Related

WPF Listbox Items

I have a ListBox control that contains the names of files inside a directory.
How would I iterate though the controls and get those names? I've tried:
for (int i = 0; i < listboxFileGroups.Items.Count; i++)
{
// I don't want to use properties that start with Selected
// Here is what I was looking for
string textItem = listboxFileGroups.Items[i].ToString();
}
Any suggestions?
You may want to explore an MVVM approach.
In one of your view model classes, you can have an ObservableCollection<string>:
public ObservableCollection<string> StuffForListBox { get; set; }
Populate that ObservableCollection with what you want to get displayed in the ListBox.
In the code-behind of the UserControl or Window in which you have the ListBox, set the DataContext to an instance of the class containing StuffForListBox seen above.
this.DataContext = new MyClass();
Alternatively you could also create a datatemplate for the usercontrol / window which will automagically wire up the datacontext with your view model.
Since you only mentioned that you want to display the files in a directory (not including sub-directories), you just need to bind the ItemsSource to StuffForListBox.
<ListBox ItemsSource="{Binding StuffForListBox}" ... >
To iterate through the strings displayed in the ListBox you just need to iterate through the ObservableCollection.
If you don't want to bother with MVVM or if that is some third party listbox, you can try grabbing the ItemsSource in the codebehind and loop through that but I'd certainly recommend MVVM. It'll make your life easier.
Now, if you wanted to get a little crazier and display things like subfolders then an ObservableCollection<string> won't cut it. You would need to create a class that contains children to model how a folder has files and subfolders.
public class DemoItem
{
public string Name { get; set; }
public DemoItem Parent { get; set; }
public ObservableCollection<DemoItem> Children { get; set; }
public bool IsSelected { get; set; }
}
...and then base your observable collection thats bound to the listbox on the above class.
If and when you do that, your listbox won't display the items properly until you create a DataTemplate But I suppose that't outside of the scope of the question :p

Adding data to DataGridView Column wise

I want to add data in Data Grid View column wise.
I am adding the column at runtime and then i want to add data to it.
Also is it possible that the columns resize themselves to fit the window.
eg-If there are 10 columns then 10 columns should fill the window else if there are 5 columns then 5 columns should fill the window
Here is the code for a simple example doing what you want. It is from the code behind for a simple form with one DataGridView control on it.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
BindingList<BindingClass> data = new BindingList<BindingClass>() {
new BindingClass { Name = "joe", Surname = "bloggs" },
new BindingClass { Name = "sue", Surname = "bloggs" } };
dataGridView1.DataSource = data;
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
}
}
public class BindingClass
{
public string Name { get; set; }
public string Surname { get; set; }
}
}
I've created a custom object to use for my data - this is where your list goes. All the public properties of lists bound to the DataGridView's datasource get created as columns - you can then hide unwanted columns.
In my example I've chosen to use a BindingList<T> rather than a List<T> - this is generally preferred since it gives you editing and can be extended to support sorting.
I also set the AutoSizeColumnsMode of the grid to Fill - there are several other options including setting the width or fill properties of each column individually, and these can also be set through the designer.
I don't recommend using a ListView since it doesn't offer automatic databinding.

Data binding access in xaml vs in code behind - Linq to XML?

I have a listbox that binds to and displays the Name elements from an XML file. When a listbox item is selected, I want to display the Price value associated with this item in a textblock. How do I retrieve the Price programmatically (meaning not in the xaml file but in code behind)? Thanks.
XML file has these nodes:
<Product>
<Name>Book</Name>
<Price>7</Price>
</Product>
I use Linq and do the select with an anonymous type. If the easiest way to access the field programmatically is through a named type, please show me how.
Here's how I bind in xaml (using a data template for each listbox item that contains):
<TextBlock Text = "{Binding Name}" />
Here's the code-behind function where I want to retrieve the Price:
private void listBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// how do I get the value of Price of the selected item here?
}
Please note that I want to access Price in this function, NOT in xaml!
First of all you probably don't even need LINQ as you can do a lot of things with XmlDocuments including doing selection via XPath (also in Bindings).
Secondly converting anonymous types to named types is trivial, if you have
select new { Name = ..., Price = ... }
You just need a class with the respective properties
select new Product { Name = ..., Price = ... }
public class Product
{
public string Name { get; set; }
public string Price { get; set; } // Datatype is up to you...
}
Thirdly you can make do without named types using dynamic.
private void listBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var listBox = (ListBox)sender;
// Named type:
Product item = (Product)listBox.SelectedItem;
// Anonymous type:
dynamic item = listBox.SelectedItem;
// <Do something with item.Price, may need to cast it when using dynamic>
// e.g. MessageBox.Show((string)item.Price);
}
You should be able to retrieve the selected item from the SelectionChangedEventArgs parameter. i.e.
var item = e.AddedItems.First();
Refer to this post - bind textblock to current listbox item in pure xaml, you can get the name both in xaml and code-behind using XmlDataProvider.

Bind a WPF data grid to multiple data sources

I have created a data grid in WPF and have 2 lists. I want to bind one column to one list and rest of the columns to another list.
Can anyone please tell me how to do this?
Thanks
Basically, You cant. The datagrid is an ItemsControl which has one ItemsSource property.
What i would do is build a view model which is a composite object that contains one of each of the items (from the two lists). then you could bind to a collection of these.
public class CompositeItem{
public Object ItemFromListOne { get; set; }
public Object ItemFromListTwo { get; set; }
}

How to bind WPF Datagrid itemssource to Collection of Collections?

What is the best approach to bind a WPF DataGrid ItemsSource to an ObservableCollection of ObservableCollections ?
e.g.
public ObservableCollection<ObservableCollection<MyDataItem>> DataValues = new ObservableCollection<ObservableCollection<MyDataItem>>();
where MyDataItem may look like this:
public class MyDataItem
{
public string Caption { get; set; }
public string DataValue { get; set; }
}
I can assume the collection of collections isn't jagged, and they all contain the same number of "columns"
Is it possible to bind each column dynamically to the 'DataValue' property of the MyDataItem objects or do I need to pack the data into an easier structure to bind to?
This is possible by using a collection-derived class as the inner object, and implementing ICustomTypeDescriptor on it - See a similar SO question on the topic (tagged with Silverlight, but same idea)
Silverlight DataGrid - Binding to a Collection of Collections of objects.

Resources