How to bind to the control's dependency property inside ControlTemplate - wpf

I've extended PopupBaseEdit control by adding my own ControlTemplate and a new DependencyProperty PopupText to the extended control. The property PopupText is initialized from the control's consumer. No issues here. The question is; how do I bind TextBox.Text to my attached property inside ControlContent?
Here is the XAML:
<ControlTemplate x:Key="myPopuptemplate">
<StackPanel>
<TextBox Margin="5" Text="???????"/>
</StackPanel>
</ControlTemplate>
<Style TargetType="local:myControl">
<Setter Property="PopupContentTemplate"
Value="{StaticResource myPopuptemplate}"/>
</Style>

Use a TemplateBinding.

Related

How to "inject" style in a DataTemplate

I am trying to separate the DataTemplates from the Styles in my code.
I use DataTemplate to define, e.g. that the data should be displayed as two buttons and I use styles to define, e.g. that the background of those buttons should be green.
What I am trying to achieve is having a DataTemplate defined in one file and using that in multiple UserControls where the style comes from the UserControls.
Let's say I have the following style in the Resources of a UserControl:
<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Foreground" Value="Green"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
Another UserControl might have something similar with different colors.
Then, I have a ContentControl in that UserControl that will have some view model and some DataTemplate:
<ContentControl Content="{Binding SelectedViewModel}"
ContentTemplate="{Binding SelectedDataTemplate}"/>
The DataTemplate can be something as simple as this:
<DataTemplate x:Key="TwoButtonsTemplate">
<StackPanel>
<Button Content="One"/>
<Button Content="Two"/>
</StackPanel>
</DataTemplate>
I would like the two buttons to have the ButtonStyle from the UserControl.Resources without directly referencing it. (So the DataTemplate can come from a different file or being able to use the DataTemplate in a similar context with another UserControl's style).
I tried to change the TargetType of ButtonStyle to ContentControl, assign the style to the ContentControl and set Foreground="{TemplatedParent Foreground}" on the Buttons, but in this way both Foreground will change when any of them (i.e. the ContentControl itself) is hovered.
Is there any way of "inheriting" a style in the DataTemplate or "injecting" the style from the UserControl?
P.S. I understand if I move the style into a separate file and reference that in the DataTemplate file I can simply use it as StaticResource, but that will couple the DataTemplate to that specific style and I won't be able to re-use it with other styles.
try DynamicResource:
<DataTemplate x:Key="TwoButtonsTemplate">
<StackPanel>
<Button Content="One" Style="{DynamicResource ButtonStyle}"/>
<Button Content="Two" Style="{DynamicResource ButtonStyle}"/>
</StackPanel>
</DataTemplate>
when TwoButtonsTemplate template is instantiated in UserControl, which declares ButtonStyle resource, that resource will be found and applied to buttons.

WPF Toolkit PropertyGrid Style

i am trying to override the wpf toolkit propertygrid's style. Therefore i modified the generic.xaml.
Now i have the problem that the defaulteditors styles are not overridden.
Therefore i wrote following style to override the PropertyGridEditorComboBox in Xaml:
<Style TargetType="{x:Type xctk:PropertyGridEditorComboBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ComboBox SelectedItem="{Binding Value}" ItemsSource="{?????}" />
</ControlTemplate>
</Setter.Value>
</Setter>
This snippet seems to work except the fact that i do not know what i have to bind as an itemssource. What do i have to bind as Itemssource?
If there is also a better way to override the DefaultEditors appearance please let me know.
KR Manuel
You have to reach from the style to the control it's applied to -- something like this:
ItemsSource="{TemplateBinding ItemsSource}"
(Assuming that PropertyGridEditorComboBox has an ItemsSource property.)

How bind to TemplatedParent from DataTemplate defined in a style?

I am developing a custom control derived from an ItemsControl. In the generic.xaml-file I created the style for that control and also defined an ItemTemplate:
<Style TargetType="local:MyItemsControl">
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<Border Background="Red">
<!-- Other things in here -->
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
I want to bind the Background property of the Border in the DataTemplate to a dependency property of the MyItemsControl.
If found several questions here suggesting to use the element name of the MyItemsControl in the binding, but that only works when defining the ItemTemplate where the control is being used. I also tried binding to a RelativeSource defining the local:MyItemsControl as ancestor type.
Nothing worked. What am I missing here?
What`s the type of that DependencyProperty? Is it Brush or string?
This simple code works for me:
Background="{Binding Name, RelativeSource={RelativeSource AncestorType=ItemsControl}}"
Just for test here I bind to Name property of ItemsControl that is 'Yellow' - and it works.

How to handle events inside a WPF DataTemplate?

I have a custom control which has a dependency property called ViewModel which value is shown inside a ContentPresenter. I have a DataTemplate for each type of ViewModel. Each template allows the user to make a selection in a different way and I need to handle that selection event in the custom control code behind.
<Style TargetType="{x:Type local:MyCustomControl}">
<Style.Resources>
<ResourceDictionary>
<DataTemplate DataType="{x:Type local:ViewModelOne}">
<!-- how to handle this event? -->
<ListBox
MouseDoubleClick="ListBox_MouseDoubleClick"/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:ViewModelTwo}">
<!-- this ListBox has another style, but event should
be handled the same way -->
<ListBox
MouseDoubleClick="ListBox_MouseDoubleClick"/>
</DataTemplate>
<!-- more templates here -->
</ResourceDictionary>
</Style.Resources>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MyCustomControl}">
<ContentPresenter Content="{TemplateBinding ViewModel}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Edit:
Here's the code behind of the custom control with the method I would like to be called when something in the ListBox is double clicked:
public class MyCustomControl : Control
{
// how to attach ListBox MouseDoubleClick event to this method?
private void ListBox_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
DoMagic(((ListBox)sender).SelectedItem);
}
}
Are these DataTemplates defined in a resource dictionary?
if so, you can use the attached behaviors.
If they are defined in a MyWindow or a MyUserControl XAML then you can defined them the code behind i.e. MyWindow.xaml.cs or MyUserControl.xaml.cs

How can i bind a IsSelected Property to a textblock

my treeview is populated with textblock items.
If a user clicks on a textblock, i want to set a property in my model called "isSelected".
But : the textblock have no Property IsSelected.
How can i Implement this ?
Derive from textblock and add a Property ?
You have to use the TreeViewItem.IsSelected property. You will have to specify the custom style for all items of the tree view.
<TreeView>
<TreeView.Resources>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsSelected" Value="{Binding IsSelected}"/>
</Style>
</TreeView.Resources>
</TreeView>

Resources