XPath syntax within binding XAML - xaml

What is the syntax for using XPath with Binding in XAML? Are there any MSDN pages which describe where to put the braces?
Visual Studio doesn't like the following:
<TextBlock Text="{Binding XPath=/One/Two[#id='0']/Three/#Four}" />
I want the Text of the TextBlock to be set to the value of the Four attribute.

Looking at the documentation, you should set the binding using nested syntax as follows:
<TextBlock>
<TextBlock.Text>
<Binding XPath="/One/Two[#id='0']/Three/#Four" />
</TextBlock.Text>
</TextBlock>

Related

Getting the datarow context or value parent in a xceed grid column group value template?

I am using an xceed DataGrid but I don't believe that matters here. What I need is how to get the databinding correct. I have a DataGrid column as follows:
<xcdg:Column FieldName="TestFieldValue"
Visible="False" Title="TestTitle"
GroupValueTemplate="{StaticResource TestFieldGroupTemplate}"/>
I am using a DataTemplate as follows:
<DataTemplate DataType="{x:Type testNamespace:TestFieldRecord}"
x:Key="TestFieldGroupTemplate">
<TextBlock Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type xcdg:DataRow}},
Path=DataContext,
Converter={StaticResource TestFieldValueConverter}}" />
</DataTemplate>
First off, the value the property tied to this column field is just a long. The DataType here on the DataTemplate is actually the parent class of the column field property. An odd thing is if I just bind the text property in the data template like Text={Binding Converter={StaticResource TestFieldValueConverter}}, the converter still gets hit but with the long value from the column.
What I need here is to either bind to the DataRow's context, or to the the parent of the column TestFieldValue, which is the testNamespace:TestFieldRecord. Any find ancestor attempts have led me to no longer hitting my converter.
I think you need to use the Snoop tool to look at the tree and DataContext to see what's happening.
Going up a couple of levels in the tree, the DataContext will be a Xceed Group.
This group has a collection of items.
Your TestFieldGroupTemplate is applying to a Group.
So the main question is where is the group title coming from?
If you just want to change the group text, you can use a DataTemplate targeting Group.
(In the paid version TableflowView this will replace all their standard stuff).
Eg this passes the Group and DataGridControl to an IMultiValueConverter converter:
<DataTemplate DataType="{x:Type xcdg:Group}">
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource AnExampleConverter}">
<Binding Path="DataContext" RelativeSource="{RelativeSource TemplatedParent}"/>
<Binding RelativeSource="{RelativeSource AncestorType={x:Type xcdg:DataGridControl}}"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>

How to data bind based on emptiness of a collection?

I want to make a TextBlock visible only when a collection is empty. I have a ListView that is data-bound to the collection already and that's simple. I just want to display something else when the ListView is otherwise empty.
I wrote an IValueConverter that would take the collection, or count, or whatever I need, and return a Visibility appropriately. The XAML looks like this:
<TextBlock Visibility="{Binding Count, ElementName=ContactsList, Converter={StaticResource visibilityWhenEmpty}}"
Text="No contacts yet. Add one using the AppBar below." />
The trouble is that binding just the collection itself only calls my value converter once, when it's empty, and not again when the contents of the collection changes (kinda makes sense). And when, as shown above, I try binding against the collection's Count property, it doesn't call my value converter at all.
Any ideas?
I have faced the same issue. I applied a tricky solution. It might work for you as well. Taks a temporary combo box and bind the collection with that.
<ComboBox x:Name="TempComboBox"
ItemsSource="{Binding DataContext.ContactsList,
RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=UserControl}}" >
<ComboBox.Template>
<ControlTemplate>
<!--Add file button..-->
<TextBlock Content="Your text..."
>
<TextBlock.Visibility>
<Binding Path="Items.Count"
RelativeSource="{RelativeSource Mode=FindAncestor,AncestorType=ComboBox}"
Converter="{StaticResource visibilityWhenEmpty}">
</Binding>
</TextBlock.Visibility>
</TextBlock>
</ControlTemplate>
</ComboBox.Template>
</ComboBox>
You could use notifyPropertyChanged for Count, or implement using BindableBase.

StringFormat in silverlight Xaml and resources

I have format strings in my resource files. I am trying to access these from the Text attribute of TextBlock using FormatString
Text="{Binding Path=Project.Name, StringFormat={Binding Path=WkStrings.DisplayProjectName, Source={StaticResource ResourceWrapper}}}"
I am getting the following error:
Provide value on 'System.Windows.Data.Binding' threw an exception
Error points to Text=.
Is it possible to access resources from a "nested binding"?
Binding.StringFormat is not a dependency property and therefore you cannot set a binding to this property. If you want to assign a value to that property, your value has to be a static resource, like this:
<TextBlock Text="{Binding ProjectName, StringFormat={StaticResource ProjectNameFormat}}"/>
You should declare your resource like this:
<UserControl.Resources>
<System:String x:Key="ProjectNameFormat">Project: {0}</System:String>
</UserControl.Resources>
The end result looks like this:
Your syntax is wrong for using StringFormat and you may want something other than StringFormat. StringFormat is used to manipulate the output of what is assigned to the Path of the Binding. In your example you're binding to the Project.Name property.
StringFormat should be used to achieve the similar effect as using String.Format in code. See this reference for formatting: http://msdn.microsoft.com/en-us/library/26etazsy(v=VS.95).aspx
Other answers around this topic:
Does Silverlight support StringFormat in binding?
http://blog.davemdavis.net/2009/12/03/silverlight-4-data-binding-string-format/
Here's some example code of using StringFormat:
<TextBlock Text="{Binding Path=Cost, StringFormat=\{0:c\}}" />

simple data binding to datagrid not happening

i have an datagrid i am trying to bind an value to label which is under datatemplate
but no binding is happening her. ?
<sdk:Label DataContext="{Binding CompanyName}" Width="50" />
i have an column which is above datatemplate there the values are getting binded.
<sdk:DataGridTextColumn Header="CompanyName" Binding="{Binding CompanyName}"/>
but in controls inside data tempalate values are not getting binded.
image field is getting binded with image source what we have specfied.
what is the issue happening here no data binding taking place . help me out
thanks in advance
prince
the issue was the the option what i was using for binding
for label to bind we have to use this property.
Content="{Binding
CompanyName}"

XAML support for local-name() in XPath

I'd like to bind to the element name of a node in my XmlDataProvider. I can't seem to get local-name() to work within my XPath expression. Does XAML support local-name()?
<TextBlock Text="{Binding XPath=local-name()}" />
I have been trying to do exactly the same thing and am pretty sure it is not supported in a single step.
The Binding.XPath help says
The XmlNode::SelectNodes method handles the XPath expressions from the XPath property. XPath functions are not supported.
However
You can work around it using a bit of a hack - you need a container around the element to provide a DataContext which is the result of your XPath and then you can query the LocalName property of that context object using Path, such as in my working example:
<StackPanel Grid.Row="20" Grid.Column="1"
DataContext="{Binding XPath=r:Result/r:LIC1}">
<TextBlock Text="{Binding Path=LocalName}" />
</StackPanel>
which I'd originally been trying to achieve with:
<TextBlock Grid.Row="20" Grid.Column="1"
Text="{Binding XPath=r:Result/r:LIC1/local-name\(\)}" />