I am having a very difficult time setting up a binding which I think should be easy. Help is greatly appreciated.
I have a resource dictionary named FormResource.xaml. In this dictionary contains a Style for the ScrollView that I redine the template for. The purpose is I want a wider vertical scrollbar on it.
<Style x:Key="LargeScrolling" TargetType="ScrollViewer">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ScrollViewer">
<Grid Background="{TemplateBinding Background}">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ScrollContentPresenter x:Name="ScrollContentPresenter"
Margin="{TemplateBinding Padding}"
ContentTemplate="{TemplateBinding ContentTemplate}"/>
<ScrollBar x:Name="PART_VerticalScrollBar"
Style="{StaticResource LargeVerticalScrollBar}"
Width="{Binding ElementName=MDTForm, Path=ScrollBarWidth}"
IsTabStop="False"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"
Grid.Column="1" Grid.Row="0" Orientation="Vertical"
ViewportSize="{TemplateBinding ViewportHeight}"
Maximum="{TemplateBinding ScrollableHeight}"
Minimum="0"
Value="{TemplateBinding VerticalOffset}"
Margin="0,-1,-1,-1"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I have a UserControl named FormControl.
public class FormControl : UserControl
I used to have this as a partial class with a XAML componenet, in which what I am trying to do worked, but I had to remove the XAML since I derive from this class in another assembly and WPF does not allow you to derive from a partial class in another assembly.
In FormControl I define a ScrollBarWidth property.
public static readonly DependencyProperty ScrollBarWidthProperty = DependencyProperty.Register("ScrollBarWidth", typeof(double), typeof(FormControl));
public double ScrollBarWidth
{
get { return (double)base.GetValue(ScrollBarWidthProperty); }
set { base.SetValue(ScrollBarWidthProperty, value); }
}
When I had this as a partial class in the main declaration I gave the FormControl class a Name of MDTForm, which is what I am using as the ElementName in my binding. I tried registering this name in FormClass.cs but no matter what I do the scrollbar is not picking up the property value.
Here is where I create my ScrollViewer in the FormControl class.
_canvasScrollViewer = new ScrollViewer();
_canvasScrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
_canvasScrollViewer.VerticalAlignment = VerticalAlignment.Top;
_canvasScrollViewer.MaxHeight = Constants.ScrollViewMaxHeight;
_canvasScrollViewer.Style = (Style)FindResource("LargeScrolling");
The only way that I got this to work was to bind to a static property. I used this for the binding.
Width="{Binding Source={x:Static form:FormControl.ScrollBarWidthP}}"
Then defined the property as such.
public static double ScrollBarWidth { get; set; }
However, I don’t want this as I can have multiple FormControl objects loaded at the same time and they may not all have the same scroll bar width property.
Use a RelativeSource Binding instead of ElementName:
This will walk up the visual tree at runtime to find the parent control containing the ScrollViewer, which solves both your scoping and multiple instance issues.