0

I have Tree View whose information are filled with a structure of a document. Every single article is represented by a single TreeView Node.

The goal is to raise the click event, pass the key that identifies that precise part of the document and render the information

I have 3 problems:

1) How can I pass the information to a different User Control 2) The Double click event works (just tried with a simple textbox) but not the single left click... :( 3) How can I open the precise part of the document I select on the treeview and repeat the operation. So e.g.: I click on the article number 3, I want the document of article 3 rendered, I click on article 5 etc. etc.

Code below:

    <UserControl x:Class="UserControls.DocumentViewLaw"
             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" 
             mc:Ignorable="d" 
             d:DesignHeight="800"  d:DesignWidth="900"
             xmlns:controls="clr-namespace:Client.UserControls">
     <Grid x:Name="grdTop">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="220"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <StackPanel Grid.Column="0" Grid.ColumnSpan="2">
            <TreeView x:Name="treeViewStructure" HorizontalAlignment="Left" Width="200" >
                <TreeView.ItemTemplate>
                    <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                        <Border x:Name="bdrTreeViewItem" HorizontalAlignment="Right" BorderThickness="2" Margin="0.5" Padding="1">
                            <TreeViewItem Header="{Binding Text}" x:Name="treeViewItem" HorizontalAlignment="Left" HorizontalContentAlignment="Left">
                            </TreeViewItem>
                        </Border>
                        <HierarchicalDataTemplate.Resources>
                            <Style TargetType="{x:Type TreeViewItem}">
                                   <EventSetter Event="MouseDoubleClick" Handler="OnTreeNodeMouseClick" />
                            </Style>
                            <Style TargetType="{x:Type Border}">
                                <Style.Triggers>
                                    <Trigger Property="IsMouseOver" Value="True">
                                        <Setter Property="BorderBrush" Value="LightBlue" />
                                        <Setter Property="BorderThickness" Value="3" />
                                        <Setter Property="CornerRadius" Value="9" />
                                    </Trigger>
                                </Style.Triggers>
                            </Style>
                        </HierarchicalDataTemplate.Resources>
                        <HierarchicalDataTemplate.Triggers>
                                <Trigger SourceName="treeViewItem" Property="IsMouseOver" Value="True">
                                <Setter TargetName="bdrTreeViewItem" Property="Background" Value="LightGray" />
                                <Setter TargetName="treeViewItem" Property="Foreground" Value="Red" />
                            </Trigger>
                        </HierarchicalDataTemplate.Triggers>
                    </HierarchicalDataTemplate>
                </TreeView.ItemTemplate>
            </TreeView>
        </StackPanel>
        <StackPanel Grid.Column="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
            <controls:TabDocumentViewLawControl x:Name="topTabLaw" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Grid.Row="0" />
        </StackPanel>
    </Grid>
</UserControl>

CodeBehind:

    using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Client.UserControls
{

    public partial class DocumentViewLaw : UserControl
    {
        public DocumentViewLaw()
        {
            InitializeComponent();
        }

        public void SetTreeViewNodeStructure(IList<TreeViewNode> nodes)
        {
         //this method is recalled in MainWindow.cs where I pass the object returned by 
         // WCF and attached to the TreeView
            this.treeViewStructure.ItemsSource = nodes;
        }

        public void OnTreeNodeMouseClick(object sender, RoutedEventArgs e)
        {
        }
    }
}

Second User Control where to visualize the document:

<UserControl x:Class="Client.UserControls.TabDocumentViewLawControl"
                 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:editor="clr-namespace:RichEditor;assembly=RichEditor"
                 mc:Ignorable="d"
                 d:DesignHeight="500" d:DesignWidth="500"
                 xmlns:vm="clr-namespace:Domain.Model.Document;assembly=Domain">
      <UserControl.Resources>
        <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
      </UserControl.Resources>
      <ScrollViewer Grid.Row="5" Grid.Column="1" MaxHeight="250">
        <StackPanel>
          <FlowDocumentReader x:Name="articoloDocumentLaw"  Grid.Row="1" Document="{Binding Path=FlowDocumentArticle}"
                           Visibility="{Binding Path=HasArticoloVisible, Converter={StaticResource BooleanToVisibilityConverter}}" />
        </StackPanel>
      </ScrollViewer>
</UserControl>

The object that I pass to the UserControl to visualize the document and his structure in "DocumentViewLaw" User Control is the single result of a result list In MainWindow component I associate the data and correspondant context.

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.Loaded += MainWindow_Loaded;
        this.login.btnLogin.Click += btnLogin_Click;
        this.tabMainControl.resultListControl.RowSelected += resultListControl_RowSelected;
    }

    void resultListControl_RowSelected(object sender, EventArgs e)
    {
        AutonomySearchResult selectedDocument = (AutonomySearchResult)this.tabMainControl.resultListControl.grdResult.SelectedItem;
        this.tabMainControl.topTabControl.SelectedItem = this.tabMainControl.tabResultList;
        Services.ServicesClient client = new Services.ServicesClient();
        var document = client.GetDocument(selectedDocument.DocKey, true);

        this.tabMainControl.topTabControl.SelectedItem = this.tabMainControl.tabDocumentView;
        this.tabMainControl.tabDocumentView.DataContext = document;

        TreeViewFactory treeFactory = new TreeViewFactory();
        var documentStructure= treeFactory.GetStructure(document.DocumentKey, document.XmlStructure, true);
        this.tabMainControl.documentViewLaw.SetTreeViewNodeStructure(documentStructure);
    }

    public virtual void onResultClick(object sender, RoutedEventArgs e)
    {
    }
}

Factory of TreeView:

public class TreeViewFactory { public IList GetStructure(DocumentKey docKey, string structure, bool loadAllParents) { //business logic with LINQ2XML }

    public class TreeViewNode
    {
        public TreeViewNode() { }

        public DocumentKey DocKey { get; set; }

        public string Text { get; set; }

        public IList<TreeViewNode> Children { get; set; }
    }

Thank u very much in advance :)

DioBrando
  • 987
  • 3
  • 10
  • 22

1 Answers1

0

1) How can I pass the information to a different User Control?

I assume that the articles data in the TreeView.ItemSource and the data in the second UserControl are bound from properties in a view model or class that is set as the DataContext of your Window or UserControl. From your view model, you can either bind to the SelectedItem property of the TreeView, or monitor the INotifyPropertyChanged interface to see when the property that is bound to the TreeView.ItemsSource is changed (by the user). At this point, you can load the required data and update whichever property is data bound to the second UserControl.

2) The Double click event works (just tried with a simple textbox) but not the single left click... :(

If you data bind as suggested above, then you will not need a Click handler, as you can find out when the user selects another node directly in the view model.

3) How can I open the precise part of the document I select on the treeview and repeat the operation. So e.g.: I click on the article number 3, I want the document of article 3 rendered, I click on article 5 etc. etc.

I don't really understand this part of your question. You should be able to access all of the properties of the selected item in the TreeView when binding to the view model.

Sheridan
  • 68,826
  • 24
  • 143
  • 183
  • Uhm, I tried adding the SelectedItem property on TreeView but didn't work really...event wasn't able to be reaised. – DioBrando Jul 22 '13 at 12:01
  • Sorry misclicked... Uhm, I tried adding the SelectedItem property on TreeView but didn't work really...event wasn't able to be raised. The problem as u can see, is that I don't use datacontext on that user control. documentStructure is a property of document. Through the TreeViewFactory I fill the object properties and pass it to the DocumentViewLaw user control. In the XAML file I use the object as ItemsSource... – DioBrando Jul 22 '13 at 12:11
  • You bind to the `TreeView.SelectedItem` property in the same way and place that you bind to the `TreeView.ItemsSource` property. Then, whenever a different node is selected in the `TreeView`, you should be able to see the property change in your view model. However, if you are not using MVVM with views and view models, and you are creating `DependencyProperty` properties to bind to in your code behind, then you will need to attach a `PropertyChangeCallbackHandler` to the `DependencyProperty` to be notified when its value changes. – Sheridan Jul 22 '13 at 12:11
  • Ahhh... in that case, I'm not sure that I can be of any help. Sorry. – Sheridan Jul 22 '13 at 12:14
  • I modified the TreeViewItem XAML this way: Dunno if it's correct, 'cause if I click for a example a child node that is child of another child node, the debugger goes 3 times in that item handler..O_o I don't use DependencyProperty :| Can u please make a simple example? Thank u very much for your help and time – DioBrando Jul 22 '13 at 12:42
  • The `Selected` event will fire each time a node is selected, so each parent node (of the child node that you clicked) will be momentarily selected before the child becomes selected. Binding to the `SelectedItem` property will just give you the child node that you selected directly. I don't really have time for example, but look here: http://stackoverflow.com/questions/7153813/wpf-mvvm-treeview-selecteditem, http://stackoverflow.com/questions/1000040/selecteditem-in-a-wpf-treeview. Bear in mind you only need read only ({Binding SelectedItem, Elementname=TreeView, Mode=OneWay}). Good luck. – Sheridan Jul 22 '13 at 13:56