Listboxes hierarchy - silverlight

I have 3 embedded listboxes for entities: group, item, subitem.
<ListBox Name="GroupItemsListBox"
ItemSource="{Binding EntityGroups"}>
<ListBox.ItemTemplate>
<DataTemplate>
<ItemsControl Name="ItemsListBox"
ItemSource="{Binding Items}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ItemsControl Name="SubItemsListBox"
ItemSource="{Binding SubItems}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name} />
</DataTemplate>
</ItemsControl.ItemTemplate>
</DataTemplate>
</ItemsControl.ItemTemplate />
</ItemsControl>
</DataTemplate>
<ListBox.ItemTemplate>
</ListBox>
Also there is a case when last listbox is empty.
I want to handle SelectedItem from the lowest existing ItemControl. So i will be able to manage when the most specific object is selected.
For example when i click on ItemGroup[1].Items[0].SubItem[2] i want to get this element, but not ItemGroup[1] or ItemGroup[1].Items[0].
How can i achieve it?

Use the LongListSelector instead. This supports grouping in a much nicer way.

Related

WPF/XAML Intuitive UserControl

what steps must be done to make a user control, to work in such order:
<local:MyUserControl ItemsSource="{Binding Items}">
<local:MyUserControl.Items>
<local:MyUserControl.Item Name="{Binding Name}"/>
</local:MyUserControl.Items>
</local:MyUserControl>
I know that for ItemsSource I need to create DependencyProperty, but what for the part which is inside MyUserControl.
Example:
Look below is an example how I used to do it.
This is called MyUserControl
<UserControl>
<Grid>
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Name}" Margin="3,3,3,3"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</UserControl>
MainPage:
<local:MyUserControl />
As you can see in this scenario, MyUserControl is not universal, it can be used properly ONLY if I have ItemsSource called Items, and inside of it there is a property called Name.
My Intention is to create flexible MyUserControl.
Thanks in advance.

Caliburn.Micro message bubbling skipping a control

I've got a hierarchical collection and I lazy load the lowest level because of it's size.
The action I'm trying to activate is on the CollectionHolderManager but it seems that the bubbling skips that visual layer for some reason.
<ItemsControl DataContext="{Binding Path=CollectionHolderManager}"
ItemsSource="{Binding Path=CollectionTopLevel}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<telerik:RadToolBar cal:Bind.Model="{Binding}">
<TextBlock x:Name="Name" />
<ItemsControl ItemsSource="{Binding Path=CollectionMiddleLevel}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<telerik:RadDropDownButton cal:Bind.Model="{Binding}"
Content="{Binding Path=Name}"
cal:Message.Attach="[Event DropDownOpened] = [Action GetLowestLevel($dataContext)]">
<telerik:RadDropDownButton.DropDownContent>
<telerik:RadListBox SelectionMode="Multiple"
ItemsSource="{Binding Path=CollectionLowestLevel}">
<telerik:RadListBox.ItemTemplate>
<DataTemplate>
<!-- some template -->
</DataTemplate>
</telerik:RadListBox.ItemTemplate>
</telerik:RadListBox>
</telerik:RadDropDownButton.DropDownContent>
</telerik:RadDropDownButton>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</telerik:RadToolBar>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
So if I have the action on the TopLevelCollection it get's called.
If I have it on the ViewModel that owns CollectionHolderManager it get's called, but not when it's on the CollectionHodlerManager itself. Why is it skipping over that?
Such a simple thing I can't believe I missed it.
<ItemsControl cal:Bind.Model="{Binding Path=CollectionHolderManager}"
ItemsSource="{Binding Path=CollectionTopLevel}">
Bind.Model instead of DataContext.

Can the groups of a grouped CollectionView be presented horizontally?

I'm implementing a ListBox whose ItemsPanel is a WrapPanel as per this answer, but there's a twist: my ItemsSource is a grouped CollectionView. With a GroupStyle applied to my ListBox, the wrapping shown in that question doesn't work: the groups are always displayed vertically.
Snooping on my app, here's why:
As you can see, the WrapPanel, defined as my ListBox's ItemsPanelTemplate, appears in the ItemsPresenter within each GroupItem; an implicit, vertically-oriented StackPanel (top item in the pink box) is created to contain the GroupItems themselves.
Is there a way to override this behavior, so the GroupItems are placed in a WrapPanel? Would I have to re-template the entire ListBox?
Update: To illustrate what I'm actually doing with my ListBox and the CollectionView grouping, let me post a little XAML:
<Grid>
<ListBox ItemsSource="{Binding}"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
SelectionMode="Multiple"
ItemContainerStyle="{StaticResource itemStyle}">
<ListBox.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" FontWeight="Bold"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListBox.GroupStyle>
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type WpfApplication1:Item}">
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Name}" FontSize="10"/>
<TextBlock Text="{Binding Amount, StringFormat={}{0:C}}" FontSize="10"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</Grid>
The GroupStyle is at the heart of it: if you remove that, the GroupItems don't get rendered, and the WrapPanel (which you can see appearing beneath the GroupItem in the screenshot above) appears in place of (StackPanel) 98 in the screenshot.
This behavior only seems to occur if you have defined a HeaderTemplate in the GroupStyle.
It can be corrected by setting the GroupStyle.Panel property to contain a WrapPanel:
<ListBox.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" FontWeight="Bold"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<WrapPanel></WrapPanel>
</ItemsPanelTemplate>
</GroupStyle.Panel>
</GroupStyle>
</ListBox.GroupStyle>
It will look something like this:
You should be able to replace the group style from the items control (ListBox):
<ListBox.GroupStyle>
<Style />
<ListBox.GroupStyle/>
Or, you should also be able to create a DataTemplate based on the group item object:
<DataTemplate DataType="{x:Type GroupItem}">
<Panel />
</DataTemplate>

WPF: How to apply data template for items in ItemsControl if items are strings?

The ItemsControl defined below is filled with string[] WeekDays. The DataTemplate defined for ItemsControl.ItemTemplate doesn't work, i.e. the week day items are not filled with red background. How do I fix this? Thanks.
...
<ItemsControl
Grid.Row="1"
Margin="20,0,0,0"
ItemsSource="{Binding Path=WeekDays}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="1" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Background="Red" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
...
Note: string[] WeekDays is a dependency property of this control. I am not sure if this information might be relevant to finding the solution.
You need to bind the TextBox's Text property to something in order it to work. So, since the data context of the data template is the string itself the binding should be like this:
<DataTemplate>
<TextBlock Text="{Binding}" Background="Red" />
</DataTemplate>

XAML ~ Need help with the Binding syntax for collection of objects

I am trying to bind a List of objects to an ItemsControl. The object has only two properties: Movie (a string) and Actors (an array of string). I can get the binding to work fine for the Movie. But I can't figure out the binding for the Actors array.
<ItemsControl x:Name="MovieList">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Width="100">
<Border Margin="2">
<TextBlock Text="{Binding Movie, Mode=OneWay}" />
</Border>
<ListBox ItemsSource="{Binding Actors, Mode=OneWay}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<controlsToolkit:WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
Any suggestions?
<ListBox ItemsSource="{Binding Actors, Mode=OneWay}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
this is wrong...you have to tell it what you want to bind to in the actors collection.
{Binding Path=ActorName} for example...since you only have it one way you could use displaymemberpath instead and just go: DisplayMemberPath="ActorName"

Resources