WinRTXamlToolkit TreeView item stretch horizontally - wpf

I'm trying to make tree view item stretch horizontally
Here is my original outcome
But what I want is this
here is my XAML code
<Grid x:Name="AgendaGrid" Grid.Row="1">
<Controls:TreeView ItemsSource="{Binding TreeItems}" Style="{StaticResource TouchTreeViewStyle}">
<Controls:TreeView.ItemTemplate>
<DataTemplate>
<data:DataTemplateExtensions.Hierarchy>
<data:HierarchicalDataTemplate ItemsSource="{Binding Children}" />
</data:DataTemplateExtensions.Hierarchy>
<Grid>
<Button Visibility="{Binding IsHeading}" Padding="0" Content="{Binding Name}" />
</Grid>
</DataTemplate>
</Controls:TreeView.ItemTemplate>
</Controls:TreeView>
</Grid>

The simple way to achieve what you want would be to use the HorizontalContentAlignment property:
<TreeView ItemsSource="{Binding Items}" HorizontalContentAlignment="Stretch" />
Unfortunately, that won't work with a TreeViewItem. That is because the ControlTemplate of the TreeViewItem features a hard coded top level Grid that has the wrong RowDefinitions set up for this requirement. Therefore, the way to fulfil your requirement is to alter the default ControlTemplate, which you can find in the TreeView Styles and Templates page on MSDN.
Rather than repeat the whole story again here, I'd rather direct you to a solution on the Horizontal stretch on TreeViewItems page of LeeCampbell's Blog. That describes the problem in a little more detail and suggests the solution of a simple tweak to the ControlTemplate.

Related

Adding a small popup on a wpf listbox that is already using itemsource

Here is a portion of my wpf-xaml code :
<ListBox x:Name="TestJobSuiteListBox" Grid.Row="1" ItemsSource="{Binding AvailableJobs}" MouseRightButtonDown="TestJobSuiteListBox_OnMouseRightButtonDown">
<ListBox.ItemTemplate>
<HierarchicalDataTemplate>
<ListBoxItem Content="{Binding Name}"/>
</HierarchicalDataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I would like to add another listboxitem to that ListBox and I dont want it to be visible before you rightclick on the listbox. It also should not be bound to the "AvailableJobs" property.
Something like this :
<ListBox x:Name="TestJobSuiteListBox" Grid.Row="1" ItemsSource="{Binding AvailableJobs}" MouseRightButtonDown="TestJobSuiteListBox_OnMouseRightButtonDown">
<ListBox.ItemTemplate>
<HierarchicalDataTemplate>
<ListBoxItem Content="{Binding Name}"/>
</HierarchicalDataTemplate>
</ListBox.ItemTemplate>
<ListBoxItem x:Name="AddJobbListBoxItem" Visibility="Hidden"></ListBoxItem>
</ListBox>
This doesn't work, because of "itemsource must be empty problem"
Anyone have a good Idea of how I could do it ?
I don't need help with the visibility/rightclick functionality.
Thanks in advance, I hope the problem is understandable.
You can put listbox to stackPanel, and disable it's scrolling. Then add that one element also to the stackPanel under the listbox, and finally add that stackPanel to scrollViewer. Then you have listbox with AddButton.
<ScrollViewer>
<StackPanel>
<ListBox ItemsSource="{Binding AvailableJobs}"
ScrollViewer.VerticalScrollBarVisibility="Disabled">
<!-- ... -->
</ListBox>
<Button x:Name="AddJobbButton" Visibility="Collapsed" />
</StackPanel>
</ScrollViewer>
Notice that if you have lots of items in listbox, there might be some performance problems, because I'm not sure that listbox's virtualizing is working correctly if it's in stackPanel.
EDIT: of course you have to listen mouse events and set then button's visibility to visible and so on...
I think you have to use ItemTemplateSelector to achieve this functionality. You can create different DataTemplate as per your requirement in the Resources section and bind properly in the xaml. Check the answer here, it will give you the idea about the approach. Please refer this examlpe also. Hope this will help.

Adcontrol InvalidCastException when inside pivot item template

I've an error with my pivot application on silverlight for Windows Phone.
To reproduce the problem, create the Pivot Application example. Change xaml to have :
<Grid x:Name="LayoutRoot" Background="Transparent">
<!--Pivot Control-->
<controls:Pivot Title="MY APPLICATION" ItemsSource="{Binding Items}">
<controls:Pivot.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding LineOne}" />
</DataTemplate>
</controls:Pivot.HeaderTemplate>
<controls:Pivot.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding LineTwo}" />
<advertising:AdControl Grid.Row="2" Grid.ColumnSpan="2" Height="80" Width="480" VerticalAlignment="Top" AdUnitId="10000000" ApplicationId="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaa" />
</StackPanel>
</DataTemplate>
</controls:Pivot.ItemTemplate>
</controls:Pivot>
</Grid>
that is an adcontrol in a pivot itemtemplate.
Don't forget to add the reference to Microsoft.Advertising.Mobile.UI and to declare namespace :
xmlns:advertising="clr-namespace:Microsoft.Advertising.Mobile.UI;assembly=Microsoft.Advertising.Mobile.UI"
then, when you run the phone application (on emulator), you have an InvalidCastException.
Without the control, no problem.
How can I solve that ?
Thanks for your help
If your trying to add views to your pivot you should be using a PivotItem. I'm almost positive the reason for the error is that your putting the AdControl inside of the ItemTemplate of the Pivot Control. There are better ways of doing this.
Instead just add a bottom margin to the pivot control of 80px. Then add the AdControl inside of the LayoutRoot and set it's Vertical Alignment to Bottom.
Not sure I would highly recommend this because of user experience, but if you want an AdControl on each view of the Pivot Control simply add the PivotItems you need and in each place an AdControl.
Bottom line: Don't place the AdControl in the ItemTemplate of the PivotControl.
That should do it.

WPF: get the content of a GroupBox to fill available space

I'm facing an irritating problem with WPF GroupBox, hope someone can help me out. Basically the problem is this: I have a listview inside a GroupBox, but no matter what I do I can't seem to be able to make it fill the GroupBox.
Here is the basic code:
<GroupBox Grid.Row="2" Header="Field" Visibility="{Binding ElementName=radioUnbound, Path=IsChecked, Converter={StaticResource bool2vis}}" Margin="0" VerticalContentAlignment="Stretch">
<ListView ItemsSource="{Binding ElementName=nnf1, Path=UnboundFields}" x:Name="listUnbound" SelectionChanged="listSelectionChanged" VerticalAlignment="Stretch" >
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding name}" Margin="2"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</GroupBox>
I tried encasing the list inside Grids, StackPanels, DockPanel, etc... but no matter what I try I always invariably end up with this:
I tried your code in XamlPad it works as you would expect it. Make sure you don't have global styles that set your ListView or GroupBox appearance.
You can clear global styles by putting this in the resources section of the GroupBox's parent control:
<Style TargetType="GroupBox" />
<Style TargetType="ListView" />

WPF UI persistence in TabControl

I am having issues with something that seems like it should be very simple but in fact has proven quite difficult.
Lets say you have a TabControl bound to an itemsource of ViewModels and the items displayed using a DataTemplate. Now lets say the DataTemplate consists of a Grid with two columns and a Grid splitter to resize the columns.
The problem is if you resize the columns on one tab, and switch to another tab, the columns are also resized. This is because the TabControl shares the DataTemplate among all tabs. This lack of UI persistence is applied to all elements of the template which can make for a frustrating experience when various UI components are adjusted. Another example is the scroll position in a DataGrid (on a tab). A DataGrid with few items will be scrolled out of view (only one row visible) if a DataGrid with more rows was scrolled to the bottom on another tab. On top of this, if the TabControl has various items defined in multiple DataTemplates the view is reset when you switch between items of differenet types. I can understand that this approach saves resources but the resultant functionality seems quite contradictory to expected UI behavior.
And so i'm wondering if there is a solution/workaround to this as i'm sure it's something that others have encountered before. I've noticed a few similar questions on other forums but there was no real solution. One about using the AdornerDecorator but that doesn't seem to work when used with a DataTemplate. I'm not keen on binding all the UI properties (like column width, scroll position) to my ViewModels and in fact I tried it for the simple GridSplitter example and I didn't manage to make it work. The width of the ColumnDefinitions were not necessarily affected by a grid splitter. Regardless, it would be nice if there were a general solution to this. Any thoughts?
If I ditch the TabControl and use an ItemsControl will I encounter a similar issue? Would it be possible to modify the TabControl Style so it doesn't share the ContentPresenter between tabs?
I've been messing with this on and off for a quite a while now. Finally, instead of trying to fix/modify the TabControl I simply recreated it's functionality. It's actually worked out really well. I made a Tab'like'Control out of a Listbox (Tab headers) and an ItemsControl. The key thing was to set the ItemsPanelTemplate of the ItemsControl to a Grid. A bit of Styling, and a DataTrigger to manage the Visibility of the Items and voila. It works perfect, each "Tab" is a unique object and preserves all it's UI states like scroll position, selections, column widths, etc. Any downsides or problems that might occur with this type of solution?
<DockPanel>
<ListBox
DockPanel.Dock="Top"
ItemsSource="{Binding Tabs}"
SelectedItem="{Binding SelectedTab}"
ItemContainerStyle="{StaticResource ImitateTabControlStyle}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel
Orientation="Horizontal">
</StackPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel
Margin="2,2,2,0"
Orientation="Horizontal" >
<TextBlock
Margin="4,0" FontWeight="Bold"
Padding="2"
VerticalAlignment="Center" HorizontalAlignment="Left"
Text="{Binding Name}" >
</TextBlock>
<Button
Margin="4,0"
Command="{Binding CloseCommand}">
<Image Source="/TERM;component/Images/Symbol-Delete.png" MaxHeight="20"/>
</Button>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ItemsControl
ItemsSource="{Binding Tabs}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl
Content="{Binding}">
<ContentControl.Style>
<Style>
<Style.Triggers>
<DataTrigger
Binding="{Binding IsSelected}" Value="False">
<Setter Property="ContentControl.Visibility" Value="Hidden" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DockPanel>

WPF - Databind to a StackPanel using DataTemplates

I've modified my question since it has changed focus when trying things out.
I narrowed the problem down to the following...
I try to bind the selected Item of a TreeView to a StackPanel (or some other container that can hold User Controls). This container will then display a UserControl, depending on the type of the selected item.
Here is the xaml of the StackPanel (both treeview and stackpanel are in the same window ==> different grid column)
<StackPanel Grid.Column="2" MinWidth="500" DataContext="{Binding ElementName=myTree, Path=SelectedItem, Mode=OneWay}">
<StackPanel.Resources>
<DataTemplate DataType="{x:Type mvTypes:MyTypeA}">
<controls:UserControlA DataContext="{Binding}" />
</DataTemplate>
<DataTemplate DataType="{x:Type mvTypes:MyTypeB}">
<controls:UserControlB DataContext="{Binding}" />
</DataTemplate>
</StackPanel.Resources>
</StackPanel>
When I place a user control directly under the stackpanel (not in the resources), it displays it with the selected object as their datacontext.
Idem if I place a TextBox in it, it will show the correct type of the selected item.
<TextBox Name="textBox1" Text="{Binding}" />
For some reason, placing it within a DataTemplate (even without setting the DataType) results in nothing to display.
Any sugestions. I'm thinking that maybe a StackPanel is not the right control for this, though I can't seem to find other controls that look suitable as containers like this.
Thanks in advance.
Replace the StackPanel in your example with ContentPresenter and instead of DataContext set the Content property. That should work.
Although you have set the Binding on the second custom control, are you setting the DataContext, as the binding is the route to the information and the DataContext is the information it applies this binding information to.
Andrew
You can create a UserControl to display the TreeView and the selection info on the right, all in one. It saves you from creating any custom control. A custom control is basically unnecessary since you do not create anything which didn't exist before.
<UserControl x:Class="NameSpace.SelectionView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="namespace.Controls"
Height="300" Width="300">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TreeView Name="customTree">
<!--Items go here-->
</TreeView>
<StackPanel Grid.Column="1" MinWidth="50" DataContext="{Binding ElementName=customTree, Path=SelectedItem, Mode=OneWay}">
<StackPanel.Resources>
<DataTemplate DataType="{x:Type StylingTest:CustomViewModelA}">
<controls:CustomADetailsControl />
</DataTemplate>
<DataTemplate DataType="{x:Type StylingTest:CustomViewModelB}">
<controls:CustomBDetailsControl />
</DataTemplate>
</StackPanel.Resources>
<TextBlock Text="{Binding}"/>
</StackPanel>
</Grid>
</UserControl>
Any other custom behaviour, I'm sure you could create or set in styles/templates here.
Also, you might find one of my other answers useful.
Good luck with wpf, cheers.

Resources