How to bind property of parent element - wpf

i have a quick Binding Question about Silverlight.
I have some Expander and want to overwrite their Header Templates
<Controls:Expander Header="MyHeaderTitle"
HeaderTemplate="{StaticResource MyExpanderHeaderTemplate}">
//Content
</Controls:Expander>
<Controls:Expander Header="MyNextHeaderTitle"
HeaderTemplate="{StaticResource MyExpanderHeaderTemplate}">
//Content
</Controls:Expander>
In the header template i have an textbox and want to bind the text to the Header of the expander.
<DataTemplate x:Key="MyExpanderHeaderTemplate">
<TextBlock Text="{Binding Path=Header}">
// some triggering stuff
</TextBlock>
</DataTemplate>
I tried some stuff with RelativeSource (Self and TemplatedParent) but nothing seems to work.
Some Ideas would be great, thx.

Take a look at RelativeSourceMode.FindAncestor
<TextBlock
Text="{Binding RelativeSource={RelativeSource RelativeSourceMode=FindAncestor, AncestorType={x:Type Controls:Expander}}}, Path=Header"/>

Just do this
<DataTemplate x:Key="MyExpanderHeaderTemplate">
<TextBlock Text="{Binding}"/>
</DataTemplate>

Thanks for the quick answers.
FindAncestor doesn't seem to work under Silverlight the Way it does in WPF (can't resolve AncestorType..)
But {Binding} or {Binding .} do the trick!

have you tried:
<DataTemplate x:Key="MyExpanderHeaderTemplate">
<TextBlock Text="{Binding .}">
// some triggering stuff
</TextBlock>
</DataTemplate>

Related

Code behind can`t find element in XAML

I have an element in my XAML called Tasklst which I was able to reference it in my code-behind without a problem. However, when I introduced a tab control (as shown below) and moved my Tasklst inside a DataTemplate, suddenly my code-behind was telling me that Tasklst cannot find it. How do I reference it now?
<dx:DXTabControl x:Name="TabControl"
ItemsSource="{Binding Sequences}"
SelectionChanged="TabControl_OnSelectionChanged"
SelectedItem="">
<dx:DXTabControl.View>
<dx:TabControlMultiLineView HeaderLocation="Bottom" />
</dx:DXTabControl.View>
<!--Header-->
<dx:DXTabControl.ItemHeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</dx:DXTabControl.ItemHeaderTemplate>
<!--Content-->
<dx:DXTabControl.ItemTemplate>
<DataTemplate>
<views:DxTaskList x:Name="Tasklst" />
</DataTemplate>
</dx:DXTabControl.ItemTemplate>
</dx:DXTabControl>
DataTemplate is the Problem here ...
you can do something like this
(DxTaskList)TabControl.Template.FindName("Tasklst", TabControl);

Dynamic Telerik RadOutlookBar headers come out wrong with ItemTemplate

I'm trying to use Telerik RadControls in a MVVM kind of way but having some strange problems.
The Viewmodel behind the RadOutlookBar has a collection of ViewModels that each have a Title string property. I wanted to define it so way the they get Wrapped inside a RadOutlookBarItem and bind the header/title properties together.
XAML:
<telerik:RadOutlookBar x:Name="Items">
<telerik:RadOutlookBar.TitleTemplate>
<DataTemplate>
<ContentControl Content="{Binding Path=Title}" />
</DataTemplate>
</telerik:RadOutlookBar.TitleTemplate>
<telerik:RadOutlookBar.ItemTemplate>
<DataTemplate>
<telerik:RadOutlookBarItem Header="{Binding Path=Title}" >
<ContentControl Content="{Binding}" />
</telerik:RadOutlookBarItem>
</DataTemplate>
</telerik:RadOutlookBar.ItemTemplate>
</telerik:RadOutlookBar>
This works as intended except that the Header comes out strange. Instead of being like a static string item it seems to get wrapped inside another object that behaves like a similar to a RadOutlookBarItem ( it' changes color when mouseover and such )
Even if I cahnge to straightforward string instead of binding it's still strange. But If I don't define a ItemTemplate inside the RadOutlookBar (that is, not a dynamic control) it looks all right.
What could be going on there?
Solved this and another problem in one fell swoop. I was binding to the wrong Template the whole time. This made me think I had to add OutLookBarItem myself.
In the end I was supposed to bind what I was trying to bind to the ContentTemplate.
<telerik:RadOutlookBar x:Name="Items">
<telerik:RadOutlookBar.ContentTemplate>
<DataTemplate >
<ContentControl Content="{Binding}" />
</DataTemplate>
</telerik:RadOutlookBar.ContentTemplate>
<telerik:RadOutlookBar.TitleTemplate>
<DataTemplate>
<TextBlock Text="{Binding DisplayName}" />
</DataTemplate>
</telerik:RadOutlookBar.TitleTemplate>
<telerik:RadOutlookBar.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding DisplayName}" />
</DataTemplate>
</telerik:RadOutlookBar.ItemTemplate>
</telerik:RadOutlookBar>
Should work I think.

How to display too long text properly in WPF ComboBox

I have a ComboBox that shows text of various lengths. For texts that are not long there is not a problem. For the texts longer than the width of ComboBox I would like to trim the text and add "..." (an ellipsis) at the end to show them properly. The bottom line is that I don't want to change the width of the ComboBox. Does anyone know how to do this?
Use a custom ItemTemplate for your ComboBox, which makes use of a TextBlock with the TextTrimming property set to CharacterEllipsis.
Example:
<ComboBox ItemsSource="..." SelectedValuePath="...">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock
Text="{Binding ...}"
TextTrimming="CharacterEllipsis" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
The answer, as Ross said, is to implement a custom ItemTemplate. However, to make it work properly, you need to do the binding properly.
A note on this method: You cannot set both the DisplayMemberPath and the ItemTemplate, it must be one or the other.
So, for the general case where the display member is the item (such as for a string), you can use binding with no properties to bind to the DataContext of the template:
<ComboBox ItemsSource="..." SelectedValuePath="...">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding }" TextTrimming="CharacterEllipsis" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Or, you can put it in a style.
<Style TargetType="{x:Type ComboBox}">
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding }" TextTrimming="CharacterEllipsis" />
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
For the case where you want to bind to a specific property of the object, similar to how you would use the DisplayMemberPath property, replace the binding with the binding that you would use to a property on the object that you are binding. So, replace the fourth line in my first example with something like this:
<TextBlock Text="{Binding MyDisplayMemberProperty}" TextTrimming="CharacterEllipsis" />
The binding is in the context of a single item of the type bound to your ComboBox. To make this more explicit, you can do the following:
<DataTemplate DataType="{x:Type namespace:MyItemType}">
<!-- My DataTemplate stuff here -->
</DataTemplate>
This will give you hints for the properties on the object while you are writing code inside the DataTemplate.
You can use TextTrimming CharacterEllipsis or WordEllipsis for the textblocks in your combobox.
Also works with a more complex DataTemplate; however, I had to resort to a DockPanel instead of the standard WrapPanel.
<ComboBox>
<ComboBox.ItemTemplate>
<DataTemplate>
<DockPanel>
<AccessText DockPanel.Dock="Left" Text="{Binding Icon}"/>
<TextBlock Text="{Binding Name}" TextTrimming="CharacterEllipsis" />
</DockPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>

Editable ItemsControl DataTemplate with MVVM pattern on WPF 4.0

I've got problem to define items in my ItemsControls (or in my view or viewModel). May be I don't know something about mvvm, but here is the question.
I have DataTemplate defined as
<DataTemplate>
<Expander>
<Expander.Header>
<StackPanel>
<TextBlock Margin="2" Text="{Binding Name}" />
<TextBlock>
<Hyperlink>
<Run Text="Delete group" />
</Hyperlink>
</TextBlock>
</StackPanel>
</Expander.Header>
<Expander.Content>
blah-blah-blah
</Expander.Content>
</Expander>
</DataTemplate>
I have a lot of Expanders, each of them have a Hyperlink. And I want the Hyperlink to delete the group - i.e. remove corresponding Expander. I have read about searching on DataTemplate with Visual and Logical - TreeHelper, but it is a bad way to solve my problem - it doesn't follow mvvm. I know that I need to write a Commmand for the Hyperlink, but how can I retrieve Expander, which I need to delete, and satisfy mvvm - that's the question.
Any advice, any suggestion...
But, if you are can't create static ICommand property for some develop reasons, you should use RelativeSource to find ancestor, which have DataContext set to ViewModel, which have this command.
<Hyperlink Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType=ItemsControl},
Path=DataContext.DeleteFileGroup}"
CommandParameter="{Binding}">
<Run Text="Delete group"/>
</Hyperlink>
All what I need to do - is craete STATIC ICommand property, and use following code
<Hyperlink Command="{x:Static vm:FileGroupViewModel.DeleteGroup}" CommandParameter="{Binding}">
<Run Text="Delete group"/>
</Hyperlink>

Element Data-Binding in Silverlight

I have a template column in a DataGrid:
<sdk:DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" >
<TextBlock Text="{Binding Name,ElementName=rsAllSkills}"/>
</StackPanel>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellEditingTemplate>
And in the same xaml file, I have
<riaControls:DomainDataSource QueryName="GetSkillsQuery" AutoLoad="True" x:Name="rsAllSkills">
<riaControls:DomainDataSource.DomainContext>
<domain:XXXX context/>
</riaControls:DomainDataSource.DomainContext>
</riaControls:DomainDataSource>
The DataSource has loaded everything successfully for sure, if I put that TextBlock out side of the DataGrid, it works; but inside the DataGrid, it doesn't load even the Name of rsAllSkills....
Could anybody give me a hint, thank you so much.
Have a dummy converter and check the binding.
What I guess is, the DataTemplate inside the CellEditingTemplate would receive the parent's DataContext, ie., DataGrid's DataContext. So, to work around this you can do one thing.
1) Bind the rsAllSkills to the Tag Property of DataGridTemplateColumn.
2) Now, Bind the TextBlock's Text property with the Tag property like,
<sdk:DataGridTemplateColumn Tag="{Binding Name,ElementName=rsAllSkills}">
<sdk:DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" >
<TextBlock Text="{Binding Tag}"/>
</StackPanel>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellEditingTemplate>
</sdk:DataGridTemplateColumn>

Resources