I've created two custom controls in wpf, Control_A and Control_B. Both of them define a ColorProperty. Control_A's ControlTemplate consists of a Control_B instance,
<ControlTemplate
TargetType="{x:Type Control_A}">
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Control_B />
</Border>
</ControlTemplate>
What I want is to bind A.Color (target) to B.Color (source). How can this be achieved in XAML?
It can be done with a TwoWay binding. This way has it's dissadvantages but it works,
<ControlTemplate
TargetType="{x:Type Control_A}">
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Control_B
Color="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Color,
Mode=TwoWay}"/>
</Border>
</ControlTemplate>
I would try to give Control_B a Name and bind to its color.
Color="{Binding ElementName=Foo, Path=Color}"
Related
I've configured ListBox to use custom ControlTemplate for it self and custom ControlTemplate for ListBoxItem. Unfortunately such change disables the default behvaiour of DisplayMemberPath property.
// resource dictionary of ListBox control template
<ControlTemplate x:Key="CustomListBox" TargetType="ListBox" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:s="clr-namespace:System;assembly=mscorlib">
<Border CornerRadius="3" BorderThickness="{TemplateBinding Border.BorderThickness}" Padding="1,1,1,1" BorderBrush="{TemplateBinding Border.BorderBrush}" Background="{TemplateBinding Panel.Background}" Name="Bd" SnapsToDevicePixels="True">
<ScrollViewer Padding="{TemplateBinding Control.Padding}" Focusable="False">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
</ControlTemplate>
//trigger code omitted
<Style TargetType="ListBox">
<Setter Property="Control.Template" Value="{StaticResource CustomListBox}"></Setter>
</Style>
// resource dictionary of ListBoxItem control template
<ControlTemplate x:Key="CustomListBoxItem" TargetType="ListBoxItem" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel>
<Border BorderThickness="0" CornerRadius="3" Padding="6 6" BorderBrush="{TemplateBinding Border.BorderBrush}" Background="White" Name="Bd" SnapsToDevicePixels="True">
<ContentPresenter Content="{TemplateBinding ContentControl.Content}" ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}" ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}" HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</Border>
<Label Height="3"></Label>
</StackPanel>
</ControlTemplate>
// trigger code omitted
<Style TargetType="ListBoxItem">
<Setter Property="Control.Template" Value="{StaticResource CustomListBoxItem}"></Setter>
<Setter Property="ItemsControl.DisplayMemberPath" Value="MatchText"></Setter>
</Style>
XAML
<ListBox x:Name="listBox" DisplayMemberPath="MyCustomText">
The DataContext of listBox is set using code. If I omit setting CustomListBoxItem as the control template, than it works as expected. How do you enable DisplayMemberPath when using custom control templates for ListBox and ListBoxItem?
I have a set of items in ItemsControl. I am displaying all of them but I want to make visible only a subset of items. So I kind of want to specify the visible area of ItemsControl (or any other element which supports this). Other elements could be seen after scrolling is applied.
I could do it on ViewModel-side and pass to ItemsControl only visible elements but I am interested in View-only solution. Is there any?
You can add a ScrollViewer in your ItemsControl's style, then if your items will overflow the width or height of the ItemsControl a ScrollBar will appear.
<Style x:Key="ItemsControlStyle1" TargetType="{x:Type ItemsControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ItemsControl}">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I followed the instruction in this blog to add ScrollIntoView to ItemsControl.
But this makes the border invisible:
<ItemsControl BorderBrush="Black"
BorderThickness="3">
<ItemsControl.Template>
<ControlTemplate>
<ScrollViewer Padding="{TemplateBinding Padding}">
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
<TextBlock Text="Test" />
<TextBlock Text="Test" />
<TextBlock Text="Test" />
</ItemsControl>
In order to display the border, I have to remove:
<ItemsControl.Template>
<ControlTemplate>
<ScrollViewer Padding="{TemplateBinding Padding}">
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
But this way I won't be able to use the ScrollIntoView method.
Any ideas? Thanks
You need to include the border in the template.
<ControlTemplate>
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ScrollViewer Padding="{TemplateBinding Padding}">
<ItemsPresenter />
</ScrollViewer>
</Border>
</ControlTemplate>
How do I enlarge those rectangles ?
I'm using wpf toolkit charts and I've tried to play with the control legend but it didn't helped.
With Blend, in the Objects panel:
Right Click on [PieSeries]
-Edit Additional Templates
-Edit LegendItemStyle
-Edit a Copy
You should get a default style:
<Style x:Key="PieChartLegendItemStyle" TargetType="{x:Type chartingToolkit:LegendItem}">
<Setter Property="IsTabStop" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type chartingToolkit:LegendItem}">
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<StackPanel Orientation="Horizontal">
<Rectangle Width="8" Height="8" Fill="{Binding Background}" Stroke="{Binding BorderBrush}" StrokeThickness="1" Margin="0,0,3,0" />
<visualizationToolkit:Title Content="{TemplateBinding Content}" />
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And your control will get a LegendItemStyle
<Charting:PieSeries ItemsSource="{Binding PutYourBindingHere}"
IndependentValueBinding="{Binding Key}" DependentValueBinding="{Binding Value}" IsSelectionEnabled="True" LegendItemStyle="{DynamicResource PieChartLegendItemStyle}">
Say I wanna put a CheckBox inside a Button. Is there anyway for me to reference that checkbox in code? i.e. In Window1.cs I want to write something like: testButton.innerCheckBox.DoStuff();
<ControlTemplate TargetType="{x:Type Button}">
<Microsoft_Windows_Themes:ButtonChrome SnapsToDevicePixels="true" x:Name="Chrome" BorderBrush="{TemplateBinding BorderBrush}" Fill="{TemplateBinding Background}" RenderDefaulted="{TemplateBinding IsDefaulted}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}" ThemeColor="NormalColor">
<Grid Width="32.083" Height="13.277">
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" HorizontalAlignment="Stretch" Margin="{TemplateBinding Padding}" VerticalAlignment="Stretch" RecognizesAccessKey="True" d:LayoutOverrides="Width, Height"/>
<CheckBox x:Name="innerCheckBox" HorizontalAlignment="Left" VerticalAlignment="Top" Content="CheckBox"/>
</Grid>
</Microsoft_Windows_Themes:ButtonChrome>
</ControlTemplate>
CheckBox innerCheckBox = testButton.Template.FindName("innerCheckBox", testButton) as CheckBox;