我正试图在Rect
中绑定ViewPort
的宽度和高度,如下所示:
<VisualBrush.Viewport>
<Rect Width="{Binding Path=MyWidth}" Height="{Binding Path=MyHeight}"/>
</VisualBrush.Viewport>
我的绑定在其他地方工作正常但在这里我收到以下错误消息:
A&#39;绑定&#39;无法设置“宽度”&#39;类型&#39; Rect&#39;的属性。 A&#39;绑定&#39;只能在DependencyObject的DependencyProperty上设置。
修改我理解错误消息。我的问题是如何解决它。如何绑定rect的高度和宽度?
答案 0 :(得分:5)
使用像这样的MultiBinding:
<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();
}
}
答案 1 :(得分:-2)
更新答案: Rect是一个结构,高度和宽度是不依赖属性(参见屏幕截图),因此它们不能绑定到任何东西。
以下是使用依赖属性和绑定的方法。
具有依赖属性的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>
输出: