Snap straight width and height in xaml

I am trying to relate the width and height Rectin the ViewPortfollowing way:

<VisualBrush.Viewport>
    <Rect Width="{Binding Path=MyWidth}" Height="{Binding Path=MyHeight}"/>
</VisualBrush.Viewport>

My binding works elsewhere, but the following error message appears here:

A “Binding” cannot be set in the “Width” property of the “Rect” type. Binding can only be set in the DependencyProperty of a DependencyObject.

Edit I understand the error message. My question is how to get around this. How to relate the height and width of a rectangle?

+4
source share
2 answers

Use MultiBinding as follows:

<VisualBrush.Viewport>
    <MultiBinding>
        <MultiBinding.Converter>
            <local:RectConverter/>
        </MultiBinding.Converter>
        <Binding Path="MyWidth"/>
        <Binding Path="MyHeight"/>
    </MultiBinding>
</VisualBrush.Viewport>

, :

public class RectConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        return new Rect(0d, 0d, (double)values[0], (double)values[1]);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}
+4

: Rect - , Height Width - (. ), .

enter image description here

, Dependency .

MyRect :

 public class MyRect : DependencyObject,INotifyPropertyChanged
{
    public MyRect()
    {            
        this.Rect = new Rect(0d, 0d, (double)Width, (double)Height);      
    }      

    private Rect rect;

    public Rect Rect
    {
        get { return rect; }
        set 
        {
            rect = value;
            RaiseChange("Rect");
        }
    }

    public double Height
    {
        get { return (double)GetValue(HeightProperty); }
        set { SetValue(HeightProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Height.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty HeightProperty =
        DependencyProperty.Register("Height", typeof(double), typeof(MyRect), new UIPropertyMetadata(1d, OnHeightChanged));

    public static void OnHeightChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
    {
        if (e.NewValue != null)
        {
            var MyRect = (dp as MyRect);
            var hight = Convert.ToDouble(e.NewValue);
            MyRect.Rect = new Rect(0d, 0d, MyRect.Rect.Width, hight);                
        }
    }

    public double Width
    {
        get { return (double)GetValue(WidthProperty); }
        set { SetValue(WidthProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Width.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty WidthProperty =
        DependencyProperty.Register("Width", typeof(double), typeof(MyRect), new UIPropertyMetadata(1d, OnWidthChanged));

    public static void OnWidthChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
    {
        if (e.NewValue != null)
        {
            var MyRect = (dp as MyRect);
            var width = Convert.ToDouble(e.NewValue);
            MyRect.Rect = new Rect(0d, 0d, width, MyRect.Rect.Height);
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void RaiseChange(string prop)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(prop));
        }
    }

}  

:

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public MainWindow()
    {           
        InitializeComponent();
        MyRect = new TabControl.MyRect();            
    }

    private MyRect myRect;
    public MyRect MyRect
    {
        get { return myRect; }
        set { myRect = value; RaiseChange("MyRect");}
    }             

    private void MySlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
    {
        if (MyRect != null)
        {
            MyRect.Height = e.NewValue/10;
            MyRect.Width = e.NewValue/10;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void RaiseChange(string prop)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(prop));
        }
    }
}

XAML:

<Window x:Class="TabControl.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        
    xmlns:local="clr-namespace:TabControl"
    Title="MainWindow" Height="450" Width="525"       
    DataContext="{Binding RelativeSource={RelativeSource Self}}"        
    >
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="80*"/>
        <RowDefinition Height="80"/>
    </Grid.RowDefinitions>        
    <Rectangle Name="recLogin" Height="300"  Width="400" DataContext="{Binding MyRect}" >
        <Rectangle.Fill>
            <VisualBrush TileMode="None" Viewport="{Binding Rect}">                    
                <VisualBrush.Visual>
                    <ScrollViewer Height="30" Width="100">
                        <Button Content="Transparent" Height="30"  Width="80" />
                    </ScrollViewer>
                </VisualBrush.Visual>
            </VisualBrush>
        </Rectangle.Fill>
    </Rectangle>        
    <Slider Maximum="20" x:Name="MySlider" Value="4" TickFrequency="1" Grid.Row="1"  TickPlacement="TopLeft" ValueChanged="MySlider_ValueChanged" />
</Grid>

:

Larger

Less

-2

Source: https://habr.com/ru/post/1626136/


All Articles