2 identical Controls in the same Grid ? (WPF/xaml) - wpf

Here is a simple code that exposes my problem :
<Grid>
<TreeView Name="myTreeViewEvent" >
<TreeViewItem Header="Employee1"/>
</TreeView>
<TreeView Name="myTreeViewEvent2" >
<TreeViewItem Header="Employee2"/>
</TreeView>
</Grid>
The thing is that my 2nd Treeview "overwrites" the 1st one...
Is there a way to change the behaviour so that the 2nd Treeview is "added" to the 1st one ?
(nb : no, I can't put them in the same Treeview cause in my "real" code, I got 2 different Treeviews that I CAN'T merge... and I gotta display them in the same grid !)

Try this
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TreeView Name="myTreeViewEvent" >
<TreeViewItem Header="Employee1"/>
</TreeView>
<TreeView Grid.Row="1" Name="myTreeViewEvent2" >
<TreeViewItem Header="Employee2"/>
</TreeView>
</Grid>
EDIT
Then what prevents you from using this approach?
<Grid>
<StackPanel>
<TreeView Name="myTreeViewEvent">
<TreeViewItem Header="Employee1"/>
</TreeView>
<TreeView Name="myTreeViewEvent2">
<TreeViewItem Header="Employee2"/>
</TreeView>
</StackPanel>
</Grid>
In this case there is no strict division. The items will strech up.

Related

Element Binding To TreeView SelectedItem Where TreeViewItem has ItemsSource

I have the following UserControl:
<UserControl x:Class="ConcreteAnalyzer.Views.CenterSectionPropertiesView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:c="clr-namespace:ConcreteAnalyzer.Converters"
xmlns:local="clr-namespace:ConcreteAnalyzer.Views"
xmlns:vm="clr-namespace:ConcreteAnalyzer.ViewModels.CenterSection"
mc:Ignorable="d">
<UserControl.Resources >
<c:DebugConverter x:Key="DebugConverter"/>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="8"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<TreeView Grid.Row="0" x:Name="CenterSectionTree">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type vm:PanViewModel}">
<TreeViewItem Header="Pan"/>
</HierarchicalDataTemplate>
</TreeView.Resources>
<TreeViewItem Header="Center Section" DataContext="{Binding CenterSection}">
<TreeViewItem Header="Front" DataContext="{Binding XPositive}" ItemsSource="{Binding Pans, Converter={StaticResource DebugConverter}}"/>
<TreeViewItem Header="Back" DataContext="{Binding XNegative}" ItemsSource="{Binding Pans}"/>
<TreeViewItem Header="Left" DataContext="{Binding YPositive}" ItemsSource="{Binding Pans}"/>
<TreeViewItem Header="Rigth" DataContext="{Binding YNegative}" ItemsSource="{Binding Pans}"/>
</TreeViewItem>
</TreeView>
<GridSplitter Grid.Row="1" Height="8" ResizeDirection="Rows" HorizontalAlignment="Stretch" ResizeBehavior="PreviousAndNext">
<GridSplitter.Template>
<ControlTemplate TargetType="{x:Type GridSplitter}">
<Grid>
<Button Content="⁞" Background="Transparent" Foreground="White"/>
<Rectangle Fill="{StaticResource TurqoiseBrush}"/>
</Grid>
</ControlTemplate>
</GridSplitter.Template>
</GridSplitter >
<ContentControl Content="{Binding SelectedItem.DataContext, ElementName=CenterSectionTree, Converter={StaticResource DebugConverter}}" Grid.Row="2">
<ContentControl.Resources>
<DataTemplate DataType="{x:Type vm:CenterSectionViewModel}">
<TextBlock Text="Center Section"/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:WallViewModel}">
<TextBlock Text="Wall"/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:PanViewModel}">
<TextBlock Text="Pan"/>
</DataTemplate>
</ContentControl.Resources>
</ContentControl>
</Grid>
This works just fine for the Treeview items that are hard-coded but if I select one of the pans, the ElementBinding does not connect. I could change the treeview to use HiearchicalDataTemplate, but to do that I think I have to create dummy collections to bind to at each level as well as add a property to the walls so that I can tell which wall is which. Creating all that dummy info just to make the treeview work has some code smell to me.
Any thoughts on the best way to get this to work?
edit:
The reason it's not working is because when the hard-coded treeview items are selected the databinding points at the TreeViewItem itself and so I was binding to the SelectedItem.DataContext. When you select a Pan, the SelectedItem is the PanViewModel, not the TreeViewItem.
If I Try simply binding to the SelectedItem, the hard-coded TreeViewItems will not work because it tries to inject the TreeViewItem itself into a ContentControl, which throws an exception.
Binding to the SelectedItem.DataContext won't work because the PanViewModel doesn't have a DataContext. I'm still not seeing an elegant solution to this.

Switch between Views according to TreeView SelectedItem

i can't find a solution to this problem.
i have a treeview, and i'm trying to get to the point where i'm clicking/double clicking and it opens a view on a different part of the window(lets say using a gridsplitter and the tree is on the right and the relevant view will open on the left by setting the contentcontrol content DP).
thanks
I used
Simplifying the WPF TreeView by Using the ViewModel Pattern
to build my Treeview.
my xaml looks like :
<TreeView ItemsSource="{Binding Parents,IsAsync=True}" Name="tree" SelectedItemChanged="tree_SelectedItemChanged" Background="Transparent" >
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:XMLParentViewModel}"
ItemsSource="{Binding Children}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="500"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition MinHeight="20" />
</Grid.RowDefinitions>
<TextBlock Text="{Binding ParentDisplayText}" TextWrapping="Wrap"/>
</Grid>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type local:XMLChildViewModel}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="500"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition MinHeight="20" />
</Grid.RowDefinitions>
<TextBlock Text="{Binding ChildDisplayText}" TextWrapping="Wrap" MouseDown="TextBlock_PreviewMouseDown" />
</Grid >
</DataTemplate>
</TreeView.Resources>
</TreeView>
and the to know what kind of element is selected :
private void tree_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
if( tree.SelectedItem.GetType() == typeof(XMLChildViewModel))
//Do what you need
}
I can adapt this code for you but if you have more questions
What clemens said, but also I have a hard time understanding what the problem/issue is? All the help we can get understanding your question, will make all the help you get even better :)
I think This will help. Here the XAML Code...
<TreeView Name="treenavigator" Grid.Row="1">
<TreeViewItem DisplayMemberPath="Item" Header="Item" Name="navitem">
<TreeViewItem Header="Add Item" Name="additem" />
<TreeViewItem Header="Update Item Details" Name="updateitem" />
<TreeViewItem Header="View Item Details" Name="viewitemdetails" />
<TreeViewItem Header="Delete Items" Name="deleteitem" />
</TreeViewItem>
</TreeView>
Here the Sample C# Code. grdForm is the grid in main window that I load the User Controller, and AddItem is the User Controller That I load into grdForm.
private void navitem_Selected(object sender, RoutedEventArgs e)
{
if (treenavigator.SelectedValue.ToString() == additem.ToString())
{
AddItem ItemView = new AddItem();
grdform.Children.Add(ItemView);
}
}

How to bind a resource to a flowdocumentreader from a treeview with only XAML?

This time I am working on a help-window mini-application (to include in the other project, the imageediting application).
I have a grid with two columns and a gridsplitter inbetween. On the left I have a treeview with several nodes (set in XAML) and on the right a flowdocumentreader.
I have about 10 resourcedictionaries where I keep my documents, one for each node, that I want to display in my flowdocumentreader. I actually have no idea how to bind this! Anybody have an idea how I can do this? My code so far (only one resourcedictionary added)
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary x:Name="About" Source="About.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="500"/>
</Grid.ColumnDefinitions>
<GridSplitter HorizontalAlignment="Right"
VerticalAlignment="Stretch"
Grid.Column="1" ResizeBehavior="PreviousAndNext" ResizeDirection="Columns"
Width="5" Background="#FFBCBCBC"/>
<TreeView Width="250" Grid.Column="0" FontFamily="Segoe UI" FontSize="16">
<TreeViewItem Header="Help">
<TreeViewItem Header="About the application"></TreeViewItem>
<TreeViewItem Header="Getting started"></TreeViewItem>
<TreeViewItem Header="Images from Flickr"></TreeViewItem>
<TreeViewItem Header="Images from the computer"></TreeViewItem>
<TreeViewItem Header="Images from the browser"></TreeViewItem>
<TreeViewItem Header="Editing">
<TreeViewItem Header="Open and Save"></TreeViewItem>
<TreeViewItem Header="Uploading"></TreeViewItem>
<TreeViewItem Header="Crop"></TreeViewItem>
<TreeViewItem Header="Resize"></TreeViewItem>
<TreeViewItem Header="Filters"></TreeViewItem>
<TreeViewItem Header="Adding text"></TreeViewItem>
<TreeViewItem Header="Remove red eyes"></TreeViewItem>
</TreeViewItem>
</TreeViewItem>
</TreeView>
<FlowDocumentReader Grid.Column="2" >
</FlowDocumentReader>
</Grid>
You could use the Tag property of the nodes to define a string value to be loaded.
Then do a binding on the selected Node's Tag.
If you then use a converter you can load your document content from file/res.Dict or whatever:
<TreeView x:Name="documentTreeView" Width="250" Grid.Column="0" FontFamily="Segoe UI" FontSize="16">
<TreeViewItem Header="Help">
<TreeViewItem
Header="About the application"
Tag="ResDict1.xaml"></TreeViewItem>
....
<FlowDocumentReader Document="{Binding ElementName=documentTreeView, Path=SelectedItem.Tag, Converter={StaticResource stringToFlowDocumentConverter}}" Grid.Column="2" />

Treeview Item Loses Selection When Focus Is Lost

I have noticed this on an application I am working on right now, so I created a simple test app to demonstrate. Below is my a window and the event handler for the treeview items. If you expand either the "One" or "Two" parent nodes, and click one of the children, the child that was selected does not show up as selected after the Focus() method is called on the text box. Instead, selection pops to the parent node. Does anyone have any idea how to overcome this, and have the selection remain with the selected child node? Thanks.
<Window
x:Class="DockingSample.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1"
WindowState="Maximized"
>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TreeView Margin="6">
<TreeViewItem Header="One">
<TreeViewItem Header="One" Selected="TreeViewItem_Selected" />
<TreeViewItem Header="Two" Selected="TreeViewItem_Selected" />
<TreeViewItem Header="Three" Selected="TreeViewItem_Selected" />
</TreeViewItem>
<TreeViewItem Header="Two">
<TreeViewItem Header="One" Selected="TreeViewItem_Selected" />
<TreeViewItem Header="Two" Selected="TreeViewItem_Selected" />
<TreeViewItem Header="Three" Selected="TreeViewItem_Selected" />
</TreeViewItem>
</TreeView>
<TextBox Grid.Column="1" x:Name="textbox" />
</Grid>
private void TreeViewItem_Selected(object sender, RoutedEventArgs e)
{
textbox.Focus();
}
With the above window and the "Selected" event handl
Give some time for TreeView to finish their events by doing this instead:
Dispatcher.BeginInvoke(DispatcherPriority.Input, new Action(() => textbox.Focus()));
Set TreeView.HideSelection to false.

Strange WPF errors in Visual Studio

Does anybody know of the reason why ""could not create instance of UserControl"" error can occur. It seems to me that it occurs completely spontanous, for example after I add space after node or change tabulation. Maybe it's some kind of VS bug?
Here are controls. This configuration actually raises an error
<UserControl x:Class="ShortcutsPrototype.KeyboardShortcutsTreePanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ShortcutsPrototype="clr-namespace:ShortcutsPrototype">
<Grid Margin="3,3,3,3">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="80" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<ShortcutsPrototype:KeyboardShortcutsTreeView />
<Button Grid.Row="1" Margin="3,3,3,3" Grid.Column="1" HorizontalAlignment="Stretch">Reset</Button>
</Grid>
</UserControl>
<UserControl x:Class="ShortcutsPrototype.KeyboardShortcutsTreeView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ShortcutsPrototype="clr-namespace:ShortcutsPrototype"
Height="300" Width="300">
<Grid>
<TreeView>
<TreeViewItem HorizontalContentAlignment="Stretch">
<TreeViewItem.Header>
<ShortcutsPrototype:KeyboardShortcutsTreeViewEntry x:Name="generalTreeViewEntry" Title="General" />
</TreeViewItem.Header>
<TreeViewItem HorizontalContentAlignment="Stretch">
<TreeViewItem.Header>
<ShortcutsPrototype:KeyboardShortcutsTreeViewEntry x:Name="generalNewFileTreeViewEntry" Title="New File" ShortcutKey="Ctrl+N" />
</TreeViewItem.Header>
</TreeViewItem>
<TreeViewItem HorizontalContentAlignment="Stretch">
<TreeViewItem.Header>
<ShortcutsPrototype:KeyboardShortcutsTreeViewEntry x:Name="generalOpenFileTreeViewEntry" Title="Open File" ShortcutKey="Ctrl+O" />
</TreeViewItem.Header>
</TreeViewItem>
<TreeViewItem HorizontalContentAlignment="Stretch">
<TreeViewItem.Header>
<ShortcutsPrototype:KeyboardShortcutsTreeViewEntry x:Name="generalSaveFileTreeViewEntry" Title="Save File" ShortcutKey="Ctrl+S" />
</TreeViewItem.Header>
</TreeViewItem>
<TreeViewItem HorizontalContentAlignment="Stretch">
<TreeViewItem.Header>
<ShortcutsPrototype:KeyboardShortcutsTreeViewEntry x:Name="generalSaveAsFileTreeViewEntry" Title="Save File As.." ShortcutKey="Ctrl+Shift+S" />
</TreeViewItem.Header>
</TreeViewItem>
</TreeViewItem>
<TreeViewItem HorizontalContentAlignment="Stretch">
<TreeViewItem.Header>
<ShortcutsPrototype:KeyboardShortcutsTreeViewEntry x:Name="debugerTreeViewEntry" Title="Debuger" />
</TreeViewItem.Header>
</TreeViewItem>
<TreeViewItem HorizontalContentAlignment="Stretch">
<TreeViewItem.Header>
<ShortcutsPrototype:KeyboardShortcutsTreeViewEntry x:Name="refactoringTreeViewEntry" Title="Refactoring" />
</TreeViewItem.Header>
</TreeViewItem>
</TreeView>
</Grid>
</UserControl>
<UserControl x:Class="ShortcutsPrototype.KeyboardShortcutsTreeViewEntry"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="25">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<Label x:Name="titleLabel" Grid.Column="0"></Label>
<Label x:Name="shortcutLabel" Grid.Column="1"></Label>
</Grid>
</UserControl>
Perhaps something in your CodeBehind file is throwing an exception. Have you checked that?
I have found that visual studio has quite the difficult time with WPF user controls.
The only thing that I can see is that it seems to use the latest compiled version of a control. Usually, building the solution will fix the errors I have. Sometimes, if I have multiple projects I have to build them manually one by one.

Resources