nyc9

hi, may i know is there is a way to get the XPath of the text data displayed in the textbox.
below is the code that displays the data(obtain through binding) in the text box:
<TextBlock MouseDown="OnMouseDown" FontSize="16" Width="200" Text="{Binding XPath =Data}"/>
I need to get the XPath in the C# codes for the OnMouseDown event function so that i can check whether the data path comes from the same parents or not. Please help.
Thanks


Re: Windows Presentation Foundation (WPF) obtaining XPath in WPF

Dr. WPF

If I understand your question correctly, then this should work:

Code Block

private void OnMouseDown(object sender, MouseButtonEventArgs e)

{

TextBlock tb = sender as TextBlock;

if (tb != null)

{

BindingExpression be = tb.GetBindingExpression(TextBlock.TextProperty);

if (be != null)

{

Binding binding = be.ParentBinding;

if (binding.XPath.ToLower() == "data")

{

// your code here

}

}

}

}

Although it seem like it would be easier to name your element and check whether the sender is that element.




Re: Windows Presentation Foundation (WPF) obtaining XPath in WPF

nyc9

hi thanks for replying.
i notice that binding.Xpath can show its xpath node name. but how do i get the whole path( if it is necessary) in order to check that the textblock clicked is within the same parent node with the other textblock. It must ensure that if the second or third textblock is clicked, and text data all is obtained from the same parent node, all of the textblock can be in focus or highlighted.
Thanks very much




Re: Windows Presentation Foundation (WPF) obtaining XPath in WPF

Dr. WPF

Okay, so you're clearly not doing what I thought you were... (seems to be a theme tonight)

When binding to an XmlDataProvider, the DataContext on the target object (in this case, the TextBlock) will be an XmlElement object. There is a property called ParentNode on the XmlElement object. It will give you the parent XmlElement object. If you need to compare the contexts of several different TextBlocks to see if they have a common parent, you would simply compare their ParentNode properties.

Code Block

private void OnMouseDown(object sender, MouseButtonEventArgs e)

{

FrameworkElement fe = sender as FrameworkElement;

if (fe != null)

{

XmlElement xe = fe.DataContext as XmlElement;

if (xe != null)

{

XmlElement parentElement = xe.ParentNode as XmlElement;

// add your code to compare to parent nodes of other elements

}

}

}

The approach described above uses object comparison for the actual CLR objects that represent the XML DOM. This is a better approach than trying to reverse-build an XPath to an object based on all of its ancestors. Such a path would always be ambiguous (because there are many ways to specify a path to the same element).




Re: Windows Presentation Foundation (WPF) obtaining XPath in WPF

nyc9

hi, thanks for the helpful reply. Just another question, may i know how to give focus or highlight the content of a text block through the use of c# code
the textblocks are created using xaml with code such as shown below:
<TextBlock MouseDown="OnMouseDown" FontSize="16" Width="200" Text="{Binding XPath =ToolTip}"/>

for example if the checking of the Xpath parent is the equal or true, how can i select which text block that has the same parent to be in focus or highlighted.

To explain further:

i have a dock panel which consist of listbox which the main data consist of 'aaaaaaaaa' and 'bbbbbbbbbb'. meanwhile in the listbox contains another list box as shown below '1'&'2' and '3'&'4' correspondingly. besides, '1' and '2' parent is 'aaaaaaaaa' according to the xml file.
_____________________________
|aaaaaaaaaaa|_________1______|
|___________|_________2______|
|bbbbbbbbbbb|________3_______|
|___________|_________4______|

The problem is that when i click on the 'aaaaaaaaaa' box it will lit up/highlighted and then later when i click on the '3' box, it will also be lit up/highlighted together with the 'aaaaaaaaaa' box.
Instead, i want the 'bbbbbbbbb' box to lit up when '3' or '4' box is selected. And the 'aaaaaaaaaa' box to lit up when '1' or '2' box is selected. in other words, the i need the highlighing to the data with the same parent only.

Thanks for your help.





Re: Windows Presentation Foundation (WPF) obtaining XPath in WPF

Dr. WPF

When the sub-listbox receives keyboard focus (see the IsKeyboardFocusWithin property), you will have to programmatically change the selection in the outer listbox. One way to do this is to walk the ancestors of the sub-listbox until you find an element of type ListBoxItem. This will be an item in the outer listbox. Just set IsSelected to true on the found ListBoxItem. (This will work as long as the outer listbox is a single-select listbox.)




Re: Windows Presentation Foundation (WPF) obtaining XPath in WPF

Dr. WPF

If the parent listbox is bound to the same XmlDataProvider as the child listbox, you may be able to simply do this in the IsKeyboardFocusWithinChanged handler for the child listbox:

Code Block

if (childListBox.IsKeyboardFocusWithin)

{

XmlElement xe = childListBox.SelectedItem as XmlElement;

if (xe != null)

{

parentListBox.SelectedItem = xe.ParentNode;

}

}

(This code is off the top of my head, so please accept that it may contain syntax errors.)






Re: Windows Presentation Foundation (WPF) obtaining XPath in WPF

nyc9

Hi, i'm not sure whether your previous code about the child list box can be used to do the functions for my application. Can you see the codes below and explain more on how to highlight the textblocks and its parent textblock when the child textblock is clicked Please help. Below is the code snippet of the xaml:

<Window.Resources>

<XmlDataProvider x:Key="dataProvider" XPath="//Show" Source="story.xml"/>

<CollectionViewSource x:Key="collView" Source="{Binding Source={StaticResource dataProvider},XPath=Folio/Story}">

</CollectionViewSource>

<DataTemplate x:Key="SecondColumnTemplate">

<StackPanel >

<TextBlock MouseDown="OnMouseDown" FontSize="16" Width="150" Text="{Binding XPath =data}" />

</StackPanel>

</DataTemplate>

</Window.Resources>

<DockPanel DataContext="{Binding Source={StaticResource dataProvider}}" ScrollViewer.VerticalScrollBarVisibility="Visible" >

<ListBox IsSynchronizedWithCurrentItem="True"

BorderThickness="1"

BorderBrush="Black"

ItemsSource="{Binding XPath=BS/Story}"

ItemTemplate="{StaticResource SecondColumnTemplate}"

>

</ListBox>

</DockPanel>

</Window>

Thank you





Re: Windows Presentation Foundation (WPF) obtaining XPath in WPF

Dr. WPF

You described having a nested listbox, but I only see one listbox in the above scenario. I would expect to see a second listbox in SecondColumnTemplate.

Am I missing something






Re: Windows Presentation Foundation (WPF) obtaining XPath in WPF

nyc9

I'm sorry. At first i intended to make the code and the problem simpler. Actually there is three columns where the third column characteristic towards the second column is exactly like the second column toward the first column. Below is the xaml codes again:


<Window.Resources>

<XmlDataProvider x:Key="dataProvider" XPath="//Show" Source="story.xml"/>

<CollectionViewSource x:Key="collView" Source="{Binding Source={StaticResource dataProvider},XPath=Folio/Story}">

</CollectionViewSource>

<DataTemplate x:Key="FirstColumnTemplate">

<StackPanel Orientation="Horizontal" >

<TextBlock MouseDown="OnMouseDown" FontSize="16" Width="150" Text="{Binding XPath =ToolTip}" />

<StackPanel Orientation="Horizontal">

<ListBox IsSynchronizedWithCurrentItem="True"

BorderThickness="1"

BorderBrush="Black"

Margin="0"

ItemsSource="{Binding XPath=Chapter}"

ItemTemplate="{StaticResource SecondColumnTemplate}"

>

</ListBox>

</StackPanel>

</StackPanel>

</DataTemplate>

<DataTemplate x:Key="SecondColumnTemplate">
<StackPanel Orientation="Vertical">
<TextBlock MouseDown="OnMouseDown" FontSize="16" Width="200" Text="{Binding XPath =Data}"/>
</StackPanel>
</DataTemplate>

<DataTemplate x:Key="SecondColumnTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock MouseDown="OnMouseDown" FontSize="16" Width="200" Text="{Binding XPath =Data}"/>
<StackPanel>
<ListBox IsSynchronizedWithCurrentItem="True"
BorderThickness="1"
BorderBrush="Black"
Margin="0"
ItemsSource="{Binding XPath=Group}"
ItemTemplate="{StaticResource ThirdColumnTemplate}"
>
</ListBox>
</StackPanel>
</StackPanel>
</DataTemplate>

<DataTemplate x:Key="ThirdColumnTemplate">

<StackPanel >

<TextBlock MouseDown="OnMouseDown" FontSize="16" Width="150" Text="{Binding XPath =Data}" />

</StackPanel>

</DataTemplate>

</Window.Resources>

<DockPanel DataContext="{Binding Source={StaticResource dataProvider}}" ScrollViewer.VerticalScrollBarVisibility="Visible" >

<ListBox IsSynchronizedWithCurrentItem="True"

BorderThickness="1"

BorderBrush="Black"

ItemsSource="{Binding XPath=BS/Story}"

ItemTemplate="{StaticResource FirstColumnTemplate}"

>

</ListBox>

</DockPanel>


</Window>





Re: Windows Presentation Foundation (WPF) obtaining XPath in WPF

nyc9

sorry, i've edited the codes again. hopefully there is no error again.... thanks in advance for ur help





Re: Windows Presentation Foundation (WPF) obtaining XPath in WPF

nyc9

i can use the codes u given below in order to do the checking:

if (fe != null)

{

XmlElement xe = fe.DataContext as XmlElement;

if (xe != null)

{

XmlElement parentElement = xe.ParentNode as XmlElement;

// add your code to compare to parent nodes of other elements

}

}

However, how do i write my codes so that if it check that the textblocks have the same parent nodes, it can be in focus or highlighted when it is clicked. Hope that i didn't confuse you....Thanks for all the help





Re: Windows Presentation Foundation (WPF) obtaining XPath in WPF

Dr. WPF

Add the OnIsKeyboardFocusWithinChanged handler to the ListBox in SecondColumnTemplate.

Within that handler, you will do something like this:

Code Block

ListBox childListBox = sender as ListBox;

if (childListBox.IsKeyboardFocusWithin)

{

XmlElement group = childListBox.SelectedItem as XmlElement;

if (group != null)

{

ListBox parentListBox = GetAncestorByType(

VisualTreeHelper.GetParent(childListBox),

typeof(ListBox)) as ListBox;

parentListBox.SelectedItem = group.ParentNode;

}

}

You can find my GetAncestorByType() function here.

If that doesn't work, it will probably be faster if you just send me a simple repro and I'll take a look.






Re: Windows Presentation Foundation (WPF) obtaining XPath in WPF

nyc9

I've send you a file to the email. Please do take a look at it...Tell me if you did not manage to received the email.Thanks...




Re: Windows Presentation Foundation (WPF) obtaining XPath in WPF

Dr. WPF

You were setting a SelectionChanged handler on the listbox... not an IsKeyboardFocusWithinChanged handler. We care about when a listbox receives focus... not when its selection changes.

All I needed to do to get the sample working is change SelectionChanged="OnIsKeyboardFocusWithinChanged" to the following:

Code Block

IsKeyboardFocusWithinChanged="OnIsKeyboardFocusWithinChanged"