Why there is no HeaderedContentControl ItemsSource property?
How then can I databind to a list of objects to be represented by HeaderedContentControl?
Thanks
John
Because ItemsSource is all about multiple pieces of content, and HeaderedContentControl has one piece of content. Put another way, HeaderedContentControl's job is to present a single object, so it doesn't need a property whose job is to feed it multiple pieces of content.
Use HeaderedItemsControl instead, or (depending on your requirements) an ItemsControl where the DataTemplate is a HeaderedContentControl. (Though in the latter case you might as well just use a Panel and multiple elements within the panel -- the HCC isn't really buying you anything.) HIC's job is to present multiple items under a single header, and it's pretty flexible. For example, the framework uses HIC as the base class for both TreeViewItem (whose "header" is the item at hand, and whose "items" are the children of that item) and MenuItem (whose "header" is the menu item, and whose "items" are any sub-menu-items, for example in a drop-down or pop-out menu).
There's no ItemsSource property, since it can have only a single child (or two children if you count Header in), just like the class it inherits from - ContentControl. Use Content property instead.
You can find more about it on MSDN.
If you want to display list of objects within HeaderedContentControl, then just add ListBox as its Content and fill ListBox with objects.
Maybe you need a HeaderedItemsControl.
You can find a sample here.
You should be able to bind the collection to the Content property.
HeaderedContentControl by name itself is a collection of ContentControl each with Header.
Related
So I have as the main user control in my WPF app a TabControl that will support several different views (basically forms for data entry) and their underlying view models (basically ORM mappings.)
I built a ContentTemplateSelector to throw out the correct content view for the selected item.
So my question is:
Should I build an ItemTemplateSelector to select the correct property from the underlying view model that will act as the tab header title?
Or, should I assign a property from each view model to another property called something like DisplayTitle and then use that in the ItemTemplate?
And more generally, is there a way to combine the "selection" of an ItemTemplate and ContentTemplate under a single selector?
I usually use type based data-templating for the content and a common property (set as DisplayMemberPath) or an attribute on the class for the header (in case there is one item per class).
I doubt that you can conveniently combine the selectors, nor do i like selectors in general...
I have a UserControl that has an ItemsControl. This ItemsControl is bound to a list of objects. To display those objects, I have *DataTemplate*s that determine how the object is presented.
I want to be able to retrieve the current values of the controls, such as Text if it is a TextBox, or SelectedItem if it is a ComboBox.
How do I iterate over these dynamically generated controls? I do not know the names of the controls, as they are generated during runtime.
Thanks..
The simplest why I could think of besides searching the visual tree for the controls and theirs template properties is probably to bind the ItemsControl data source to an ObservableCollection. This why you can dynamically add any type of controls to the list.
Once you do that, you can easily check the type of each UIElement within the list. e.g; if it's a Textbox then get the text property by casting, etc.
I have several controls in my WPF window. I have divided the window into 4 sections. If I click on the section in the upper left, I want to copy the contents of this section in another window popup.
What I want to copy is a grid that can contain a lot of different controls, ex: togglebutton, button, panel... derived from ItemsControl, Control... and with DependencyProperty, ObservableCollection etc..
I tried :
XamlWriter.Save(data);
XamlServices.Save(data);
but I always have these errors :
Cannot serialize a generic type 'System.Collections.ObjectModel.ObservableCollection`1 or
A BadImageFormatException has been thrown while parsing the signature. This is likely due to lack of a generic context. Ensure
genericTypeArguments and genericMethodArguments are provided and
contain enough context.
You should not clone XAML itself, this is brutal and wrong way.
Take a look at the possible MVVM solution below. Let's say single DataGird represents a single business Item, so you need following:
ItemsWindow.xaml - represents a ListView and single item of ListView is DataGrid representing an item details
ItemsViewModel - expose list of Item objects (ObservableCollection<Item> Items { get; set; })
Each item of the ItemsWindow.ListView is represented by a DataTemplate like ItemDataTemplate
ItemsViewModel exposed command ICommand CopyItem and in command handler actually copyiing only instance of the Item business entity and adding it to the Items list, WPF reflects this changes via bindings and UI will be updated by a new ListViewItem with a DataGrid representing a details of just copied Item
Useful links:
Model View ViewModel pattern
Commands
Data Templating Overview - short and clean overview of WPF data templates with examples
Assume that I need to create a class called PictureWall, which will be used to show pictures.
Now I find that Panel and ItemsControl can both be used to hold Children elements. So should the class PictureWall derive from Panel? or should it derive from ItemsControl.
Note: This is not a real requirement, it's just a hypothetical question. The real question is: when should I create a subclass of Control (or ItemsControl) and when should I create a subclass of Panel?
Note 2: This imagined picture wall control is not to be used in one application only. It may be used by other developers. If it derives from Panel or ItemsControl, it'll expose the property named Children to other developers. So in this case, deriving from Control is a better idea, right?
Note 3: This imagined picture wall control has its own default way of loading certain pictures (for example, pulling pictures from a server) and it does not want this way to be messed around. If this is the case, then we should not inherit ItemsControl, right?
Panel is a container that is used to arrange its children. For example: Grid with a title and one button on the bottom and an image on center - Grid is very flexible to help you move stuff and arrange them when you change the size of window etc.
ItemsControl is a control that helps you with a collection of items. Let's take a concrete example: Listbox. You can very easly show a list of items, applay template to all of them, so on and so forth.
Control class is basically a UI element that can have its own template.
Note that, it is a way much better to define own UserControl, edit template or style of your PictureWall, insted of subclassing (there are many advantages, for example you can use Blend to redefine the style).
Edit:
# note2
If I were you I would make my own User Control to reuse existing controls to make what I want. If that won't be enough I would subclass Control.
[StyleTypedProperty(Property = "FooStyle", StyleTargetType = typeof(Control))]
public partial class MyDangControl: Control
{
...
# note3
This is a bad idea to combine all in one. You should split the logic that fetch the data form yout Picture Wall. For instance, user presses thumbnail to download the image and whole UI hangs. Horrible UX.
To be crystal clear, let me quote Pro WPF in C# 2010
Control
This is the most common starting
point when building a control
from scratch. It’s the base class for
all user-interactive widgets. The
Control class adds properties for
setting the background and foreground,
as well as the font and alignment of
content. The control class also places
itself into the tab order (through the
IsTabStop property) and introduces the
notion of double-clicking (through the
MouseDoubleClick and
PreviewMouseDoubleClick events). But
most important, the Control class
defines the Template property that
allows its appearance to be swapped
out with a customized element tree for
endless flexibility.
ContentControl
This is the base class for controls
that can display a single piece of
arbitrary content. That content can be
an element or a custom object that’s
used in conjunction with a template.
(The content is set through the
Content property, and an optional
template can be provided in the
ContentTemplate property.) Many
controls wrap a specific, limited type
of content (like a string of text in a
text box). Because these controls
don’t support all elements, they
shouldn’t be defined as content
controls.
ItemsControl
ItemsControl is the base class for
controls that wrap a list of items but
don’t support selection, while
Selector is the more specialized base
class for controls that do support
selection. These classes aren’t often
used to create custom controls,
because the data templating features
of the ListBox, ListView, and TreeView
provide a great deal of flexibility.
Panel
This is the base class for controls
with layout logic. A layout control
can hold multiple children and
arranges them according to specific
layout semantics. Often, panels
include attached properties that can
be set on the children to configure
how the children are arranged.
They both can be used to display elements, but really an ItemsControl offers much more functionality. In addition, an ItemsControl doesn't really display it's elements, it leverages a Panel to do that.
An ItemsControl can display a list of items, which may or may not be UIElements/Visuals. The items can be templated using a configurable DataTemplate, which ultimately determines how the item is displayed. In addition, then items can be bound to an observable collection so it will automatically update.
Neither of these features are supported by a Panel. DataTemplates can be used, but you have to manually create an associated ContentControl/ContentPresenter and add it to your panel.
Ultimately, their functions are different. A Panel is used to display UIElements/Visuals. An ItemsControl is used to display any type of data and apply templates as needed.
I have got an ObservableCollection<Button> buttonList; (this can be any other control: TextBox, TextBlock or even a UserControl).
I want to bind this List via DataBinding to a parent control (lets say a Grid or a WrapPanel,...)
Is this somehow possible? Children property is read only.
I do not want to do this in the program code -> Dont iterate through the list and add every item to the children property.
I want to BIND the List to a parent control -> the View is automatically updated, every time I add a new Item to the List.
Any Ideas?
Use ItemsControl, and bind your collection to ItemsSource.
And don't forget to read Dr. WPF's articles: ItemsControl: A to Z. This is second time I'm mentioning this blog today here, but he really-really deserves to be mentioned in every post related to collection of items and bindings :).
Cheers, Anvaka.