Question

I derived from the System.Windows.Controls.ScrollViewer and changed the Template; my idea was to create a ScrollViewer as seen in Visual Studio 2010, which has a small ComboBox to set the zoom into the text.

The "ZoomPercentageValueComboBox" has the following DependencyProperty:

public double ZoomValue
{
    get { return (double)GetValue(ZoomValueProperty); }
    set { SetValue(ZoomValueProperty, value); }
}

public static readonly DependencyProperty ZoomValueProperty =
    DependencyProperty.Register("ZoomValue", typeof(double),
    typeof(ZoomPercentageComboBox), new FrameworkPropertyMetadata(1D, FrameworkPropertyMetadataOptions.Journal,
        new PropertyChangedCallback(ZoomValue_PropertyChanged)));

private static void ZoomValue_PropertyChanged(DependencyObject dpo, DependencyPropertyChangedEventArgs dpcea)
{
    ((ZoomPercentageComboBox)dpo).Text = (((double)dpcea.NewValue) * 100).ToString() + " %";
}

The new ScrollViewer has the following method:

private static ControlTemplate CreateDefaultControlTemplate()
{
    #region DEFAULT
    ControlTemplate template = null;
    FrameworkElementFactory factory = new FrameworkElementFactory(typeof(Grid), "Grid");
    FrameworkElementFactory child = new FrameworkElementFactory(typeof(ColumnDefinition), "ColumnDefinitionOne");
    FrameworkElementFactory factory3 = new FrameworkElementFactory(typeof(ColumnDefinition), "ColumnDefinitionTwo");
    FrameworkElementFactory factory4 = new FrameworkElementFactory(typeof(RowDefinition), "RowDefinitionOne");
    FrameworkElementFactory factory5 = new FrameworkElementFactory(typeof(RowDefinition), "RowDefinitionTwo");
    FrameworkElementFactory factory6 = new FrameworkElementFactory(typeof(ScrollBar), "PART_VerticalScrollBar");
    FrameworkElementFactory factory7 = new FrameworkElementFactory(typeof(ScrollBar), "PART_HorizontalScrollBar");
    FrameworkElementFactory factory8 = new FrameworkElementFactory(typeof(ScrollContentPresenter), "PART_ScrollContentPresenter");
    FrameworkElementFactory factory9 = new FrameworkElementFactory(typeof(Rectangle), "Corner");
    Binding binding = new Binding("HorizontalOffset")
    {
        Mode = BindingMode.OneWay,
        RelativeSource = RelativeSource.TemplatedParent
    };
    Binding binding2 = new Binding("VerticalOffset")
    {
        Mode = BindingMode.OneWay,
            RelativeSource = RelativeSource.TemplatedParent
    };
    factory.SetValue(Panel.BackgroundProperty, new TemplateBindingExtension(Control.BackgroundProperty));
    factory.AppendChild(child);
    factory.AppendChild(factory3);
    factory.AppendChild(factory4);
    factory.AppendChild(factory5);
    factory.AppendChild(factory9);
    factory.AppendChild(factory8);
    factory.AppendChild(factory6);
    factory.AppendChild(factory7);
    child.SetValue(ColumnDefinition.WidthProperty, new GridLength(1.0, GridUnitType.Star));
    factory3.SetValue(ColumnDefinition.WidthProperty, new GridLength(1.0, GridUnitType.Auto));
    factory4.SetValue(RowDefinition.HeightProperty, new GridLength(1.0, GridUnitType.Star));
    factory5.SetValue(RowDefinition.HeightProperty, new GridLength(1.0, GridUnitType.Auto));
    factory8.SetValue(Grid.ColumnProperty, 0);
    factory8.SetValue(Grid.RowProperty, 0);
    factory8.SetValue(FrameworkElement.MarginProperty, new TemplateBindingExtension(Control.PaddingProperty));
    factory8.SetValue(ContentControl.ContentProperty, new TemplateBindingExtension(ContentControl.ContentProperty));
    factory8.SetValue(ContentControl.ContentTemplateProperty, new TemplateBindingExtension(ContentControl.ContentTemplateProperty));
    factory8.SetValue(CanContentScrollProperty, new TemplateBindingExtension(CanContentScrollProperty));
    factory7.SetValue(ScrollBar.OrientationProperty, Orientation.Horizontal);
    factory7.SetValue(Grid.ColumnProperty, 0);
    factory7.SetValue(Grid.RowProperty, 1);
    factory7.SetValue(RangeBase.MinimumProperty, 0.0);
    factory7.SetValue(RangeBase.MaximumProperty, new TemplateBindingExtension(ScrollableWidthProperty));
    factory7.SetValue(ScrollBar.ViewportSizeProperty, new TemplateBindingExtension(ViewportWidthProperty));
    factory7.SetBinding(RangeBase.ValueProperty, binding);
    factory7.SetValue(UIElement.VisibilityProperty, new Te emplateBindingExtension(ComputedHorizontalScrollBarVisibilityProperty));
    factory7.SetValue(FrameworkElement.CursorProperty, Cursors.Arrow);
    factory7.SetValue(AutomationProperties.AutomationIdProperty, "HorizontalScrollBar");
    factory6.SetValue(Grid.ColumnProperty, 1);
    factory6.SetValue(Grid.RowProperty, 0);
    factory6.SetValue(RangeBase.MinimumProperty, 0.0);
    factory6.SetValue(RangeBase.MaximumProperty, new TemplateBindingExtension(ScrollableHeightProperty));
    factory6.SetValue(ScrollBar.ViewportSizeProperty, new TemplateBindingExtension(ViewportHeightProperty));
    factory6.SetBinding(RangeBase.ValueProperty, binding2);
    factory6.SetValue(UIElement.VisibilityProperty, new TemplateBindingExtension(ComputedVerticalScrollBarVisibilityProperty));
    factory6.SetValue(FrameworkElement.CursorProperty, Cursors.Arrow);
    factory6.SetValue(AutomationProperties.AutomationIdProperty, "VerticalScrollBar");
    factory9.SetValue(Grid.ColumnProperty, 1);
    factory9.SetValue(Grid.RowProperty, 1);
    factory9.SetResourceReference(Shape.FillProperty, SystemColors.ControlBrushKey);

    #endregion

    /* *** */
    factory7.SetValue(MarginProperty, new Thickness(ZoomBoxWidth, 0, 0, 0));
    /* *** */
    FrameworkElementFactory factory10 = new FrameworkElementFactory(typeof(ZoomPercentageComboBox), ZoomBoxTemplateName);
    factory.AppendChild(factory10);
    factory10.SetValue(Grid.ColumnProperty, 0);
    factory10.SetValue(Grid.RowProperty, 1);
    factory10.SetValue(ZoomPercentageComboBox.HorizontalAlignmentProperty, 
        HorizontalAlignment.Left);
    factory10.SetValue(ZoomPercentageComboBox.HeightProperty, 17D);
    factory10.SetValue(ZoomPercentageComboBox.WidthProperty, ZoomBoxWidth);
    factory10.SetValue(ZoomPercentageComboBox.IsEditableProperty, true);
    factory10.SetValue(ZoomPercentageComboBox.VerticalContentAlignmentProperty, VerticalAlignment.Top);
    factory10.SetValue(ZoomPercentageComboBox.HorizontalContentAlignmentProperty, HorizontalAlignment.Left);
    factory10.SetValue(ZoomPercentageComboBox.FontSizeProperty, 10D);
    factory10.SetValue(ZoomPercentageComboBox.FontFamilyProperty, new FontFamily("Arial"));
    factory10.SetValue(ZoomPercentageComboBox.BorderBrushProperty, null);
    factory10.SetValue(ZoomPercentageComboBox.BorderThicknessProperty, new Thickness(0));

    /* **************************************************************
???
    */

    template = new ControlTemplate(typeof(LSArbeitscanvasScrollViewer))
    {
        VisualTree = factory
    };
    template.Seal();

    return template;
}

THis is actually taken from the original ScrollViewer. Now I want to make shure that if the "ZoomValueProperty" from the ComboBox changes, the DependencyProperty "ZoomPercentageValueProperty", which is a class member of the ScrollViewer, changes, too. I had the idea to do it like this:

Binding binding = new Binding("HorizontalOffset")
    {
        Mode = BindingMode.OneWay,
        RelativeSource = RelativeSource.TemplatedParent
    };

but this didn't really work

Was it helpful?

Solution

I finally solved this by using a RoutedEvent in the class of the ComboBox and checking wheter the Source of the event is the templated ComboBox:

private void ZoomPercentageComboBox_ZoomValueChanged(object sender, ZoomValueChangedEventArgs e)
{
    if (e.Source == templatedZoomPercentageComboBox)
        ZoomPercentageComboBoxZoomPercentageValue = ((double)e.NewValue);
}

private const string ZoomBoxTemplateName = "PART_ZoomBox";

private ZoomPercentageComboBox templatedZoomPercentageComboBox
{
    get
    {
        return this.GetTemplateChild(ZoomBoxTemplateName) as ZoomPercentageComboBox;
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top