I'm using Telerik WPF controls but I'll appreciate any suggestions that might be helpful.
I have a GridView (RadGridView with RadGridView.RowDetailsTemplate actually, but it doesn't really matters). Also I have a collection of Images (It's actually a ICollection where items of this collection are relative Uris to the Images). Everything works fine if I have a fixed amount of Images in my collection, because I can create a fixed amount of Image controls in my View (XAML) and create a binding for each of these images in collection to each of my Image controls.
I want to create a mini-gallery. The question is how can I generate a non-fixed amount of Image controls to be shown in my GridView.RowDetails (or tell me if there is another way to display a list of images) during runtime. I'd like to know if there are few ways to do this (i.e. through binding in XAML and throught the Code.
Thank you in advance.
I will use CellTemplate to do this.
Basically, you will need a collection of ImageSource/Uri, which will be the ItemsSource of the DataGrid/RadGridView. This collection should implement INotifyCollectionChanged and INotifyPropertyChanged, e.g. ObservableCollection<T>. So you code behind or view model, you could build this collection dynamically, and bind the Source property of your Image in Xaml.
Sample Code
Note the sample code here are for MS DataGrid, but the Telerik RadGridView has the similar interface, so you will be able to easily modify you code.
In Xaml, you could have something like following:
<Grid>
<Grid.Resources>
<DataTemplate x:Key="DataTemplate1">
<Image Source="{Binding}"/>
</DataTemplate>
</Grid.Resources>
<DataGrid ItemsSource="{Binding}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn CellTemplate="{StaticResource DataTemplate1}"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
C# code will be like:
var items = new ObservableCollection<Uri>();
this.DataContext = items;
for (int i = 1; i < 4; i++)
{
items.Add(new Uri("youimage.jpg"));
}
Related
I have XML file with my items and I'm deserializing them into ObservableCollection<UserControl> and I want to put it to my ItemsControl with my own layout.
Now I've created my own UserControl to handle deserialized data to layout and ObservableCollection is binded to my ItemsControl but if I want to display more than 5-10 items my app if getting unresponsive for a while.
How can I avoid freezes? Should I use DataTemplate within ItemsControl or any other ideas? I'm wondering how its done in apps like twitter or reddit which have many entries and everything is working quite nice. Have already searched for reddit/twitter app source to look how they have implemented it, but without success.
EDIT:
xaml
<ScrollViewer>
<ItemsControl x:Name="items" ItemsSource="{Binding}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
c#
public MainPage()
{
this.InitializeComponent();
items.DataContext = _items;
}
public ObservableCollection<my_item> _items = new ObservableCollection<my_item>();
adding items
for (int i = 0; i < 40; i++)
{
_items.Add(new my_item());
}
my_item is my own UserControl with 2 small images, few buttons and a single TextBlock.
You should use ListView which has a virtualizing panel for displaying items by default:
<ListView ItemsSource={Binding Items} >
<ListView.ItemTemplate>
<DataTemplate>
<!-- here goes your item layout -->
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Maybe one reason for your app "hanging" is if you are deserializing/parsing your XML file on the UI thread, especially if the XML file is large, so the solution to this problem is that you need to do the XML parsing on a background thread:
Task.Run(() =>
{
var items = ParseXML();
});
After edit:
1)
Don't wrap an ItemsControl inside a ScrollViewer, because you will break the virtualization. The ItemsControl itself has its own ScrollViewer so there is no need of an additional one.
If you are on Windows Phone 8.1 Runtime, use ItemsStackPanel instead of VirtualizingStackPanel.
2)
It is recommended for lists with many items to use DataTemplates instead of filling it with UI elements. So rather create a data template from your user control:
<DataTemplate>
<MyUserControl/>
</DataTemplate>
I am attempting to populate a ScrollerViewer control with an arbitrary number of of UserControls (Views) whilst using the MVVM pattern and bindings.
I am using an ObservableCollection to maintain my View collection and I have this collection set as the datacontext for my ScrollViewer control, however, getting the views to appear in the scroll viewer has had me going round in circles for a while now.
Can someone please point me to either a suitable example, or kindly provide an example which demonstrates the functionality I am attempting to achieve here?
Many thanks,
First off, I think you want an ItemsControl, not a ScrollViewer. Once you do that, assuming that your ObservableCollection of viewmodels is called "Items":
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<uc:MyControl DataContext="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Replace the <uc:MyControl DataContext="{Binding}"/> with a reference to your UserControl.
I am somewhat new to WPF and Data Binding, it seems very powerful. I'm wondering if there's a way to have a set of labels, and have there Content property all binded to a different index in array of strings. So then as the array is updated, the labels automatically change too.
The xaml syntax is still a bit foreign to me and I haven't been able to get it to work.
If this is a dynamic set of labels, then you may be better off using an ItemsControl, and changing its ItemTemplate to display a label for each item in the collection that it is bound to (a collection of strings in your case).
Something like:
<ItemsControl ItemsSource="{Binding MyLabelStrings}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Label Content="{Binding}" ... />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
As Bojin mentions, if you wish your UI to update if strings are added/removed from the collection, then use an ObservableCollection for the MyLabelStrings property.
I am just learning XAML and programming for Windows Phone 7.
Im trying to create an itemtemplate for a WP7 Pivot Control. I was able to make a template which contains a listbox. Is it possible to access this listbox in the code-behind so I can fill it based on a collection of a custom class? Basically how it works is that I have a pivot control and each item in that control is a category. For each category thatis added, there is a list of items that belong to that category. I need to be able to populate the list on each pivot item with items of that category.
I searched for ideas on how to accomplish this, and I get a lot of examples on databinding, but Im not too familiar on how databinding works in XAML.
Would databinding be the way to go or can I somehow get a reference to the listbox and add the items myself?
Any help would be greatly appriciated!
Thank you
I've some considerations on subject:
1) If you fill Categories list via binding, then you don't have entry point where binding is guaranteed comleted (because binding executes in deferred fashion).
2) Working with ItemTemplate's content is more tricky and unreliable, than DataTemplate approach, and you should use it just in exclusive situations. LogicalTreeHelper and VisualTreeHelper classes will help you.
3) But I would recommend you to build your view based on DataTemplates as it is common practice in WPF. Do you really think that this code is pretty complicated?
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow">
<Window.Resources>
<DataTemplate x:Key="InnerItemDataTemplate">
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
<DataTemplate x:Key="CategoryDataTemplate">
<StackPanel>
<ListView ItemsSource="{Binding InnerItems}"
ItemTemplate="{StaticResource InnerItemDataTemplate}"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<ListView ItemsSource="{Binding Categories}"
ItemTemplate="{StaticResource CategoryDataTemplate}"/>
</Grid>
public class Category
{
public IEnumerable<InnerItem> InnerList
{
get{/*...*/}
}
}
class InnerItem
{
public string Name
{
get{/*...*/}
}
}
public class SampleModel
{
public IEnumerable<Category> Categories
{
get {/*...*/}
}
}
IF you create a new "Windows Phone Pivot Application" the default code shows an example of this but reuses the same items in the listbox in multiple pivotitems.
Here's an overview of what that sample code is doing and how you might go about changing it.
In the constructor of MainPage, the DataContext is set to an object (App.ViewModel).
This Loaded event of MainPage ensures that App.ViewModel is populated.
App.ViewModel is an instance of MainViewModel.
MainViewModel contains an ObservableCollection called "Items". It is this that is bound to an idividual ListBox in a PivotItem:
<controls:PivotItem Header="first">
<ListBox ItemsSource="{Binding Items}">
...
</ListBox>
</controls:PivotItem>
Within the ListBox, you can refer to the contents of the "Items" collection.
If you wanted to adjust this to have different collections for each ListBox/PivotItem you could just adjust this to have multiple collections in the MainViewModel.
HTH.
I want brief knowledge about Data Template for Customizing a control(like Combo Box,List Box etc.)in WPF using C#.NET. So if anybody have any links or sample applications then share it with me please..
Update:
I got to know the DataTemplate in some what but now I want to know about the terms used for DataTemplate like ObservableCollection,DataContext and how to set the Binding property according to the User's need. I want an idea for develop a very similar kind of Sample application like dividing Combo Box's each items into three Column and adding different contents on different columns dynamically
Thanks in Advance
here is it used very simply - but basically a DataTemplate allows you to represent data using XAML
<ItemsControl ItemsSource="{Binding Path=SomeDataCollection}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=SomeProperty}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
You should check out the WPF Quiz demo : http://community.infragistics.com/pixel8/media/p/91950.aspx It will teach you MVVM and the power of DataTemplates in one go :)
Suppose you want to show the button in each item of ComboBox , so you can do this by overriding its ItemTemplate method
<ComboBox>
<ComboBox.ItemTemplate>
<DataTemplate>
<Button Content="Sa"></Button>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
and in the code behind
List<string> lst = new List<string>();
for (int i = 0; i < 5; i++)
{
lst.Add("Sa" + i.ToString());
}
cmb.ItemsSource = lst;
so now when you run this , you will get the desired output , each combo item will be a button