【发布时间】:2019-10-28 09:53:22
【问题描述】:
我希望能够向我的画布动态添加不同的(自行创建的)“小部件”并使用Canvas.Top 和Canvas.Left 定位它们。
我已经能够使用Canvas.Children.Add() 添加项目,但我不知道如何创建与Top 和Left 值的绑定。
以某种方式将Canvas 的内容绑定到一个列表并在 XAML 中创建所有绑定会更好吗?那么,我该怎么做呢?
【问题讨论】:
我希望能够向我的画布动态添加不同的(自行创建的)“小部件”并使用Canvas.Top 和Canvas.Left 定位它们。
我已经能够使用Canvas.Children.Add() 添加项目,但我不知道如何创建与Top 和Left 值的绑定。
以某种方式将Canvas 的内容绑定到一个列表并在 XAML 中创建所有绑定会更好吗?那么,我该怎么做呢?
【问题讨论】:
如果你不知道 UWP 中的绑定,可以看这个document。
根据你的情况,可以考虑使用MVVM进行绑定,在Code-Behind中创建ViewModel,在xaml中使用Binding绑定相关属性。
CanvasPageViewModel.cs
public class CanvasPageViewModel : INotifyPropertyChanged
{
private double _rectTop;
public double RectTop
{
get => _rectTop;
set
{
_rectTop = value;
OnPropertyChanged();
}
}
private double _rectLeft;
public double RectLeft
{
get => _rectLeft;
set
{
_rectLeft = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName]string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
CanvasPage.xaml.cs
public CanvasPageViewModel viewModel = new CanvasPageViewModel();
public CanvasPage()
{
this.InitializeComponent();
this.DataContext = viewModel;
viewModel.RectTop = 20;
viewModel.RectLeft = 100;
}
CanvasPage.xaml
<Grid>
<Canvas Width="500" Height="500" Background="White">
<Rectangle Width="50" Height="50" Fill="Blue"
Canvas.Top="{Binding RectTop}"
Canvas.Left="{Binding RectLeft}"/>
</Canvas>
</Grid>
这是一个简单的例子。如果以后想修改控件的位置,可以直接修改数据源,UI会同步。
更新
如果需要手动添加Canvas的子元素,可以使用这个方法:
var myRect = new Rectangle()
{
Height = 50,
Width = 100,
Fill = new SolidColorBrush(Colors.Blue)
};
myCanvas.Children.Add(myRect);
但是如果要绑定创建的Rectangle元素,如你所说,绑定Canvas.Left属性,可以这样写:
public CanvasPageViewModel viewModel = new CanvasPageViewModel();
public CanvasPage()
{
this.InitializeComponent();
var myRect = new Rectangle()
{
Height = 50,
Width = 100,
Fill = new SolidColorBrush(Colors.Blue)
};
Binding leftBinding = new Binding()
{
Path = new PropertyPath("RectLeft"),
Mode=BindingMode.OneWay
};
myRect.SetBinding(Canvas.LeftProperty, leftBinding);
myCanvas.Children.Add(myRect);
}
最好的问候。
【讨论】:
ListView.ItemsSource一样使用Canvas吗?这可能不符合绑定的设计。绑定意味着绑定数据而不是绑定UIElement。可以使用myCanvas.Children.Add(uiElement)手动添加子元素,但不建议使用绑定来完成。
Canvas.Children.Add(),我无法弄清楚如何为Canvas.Top 和Canvas.Left 创建绑定,因为它们是源自DependencyPropertys 的DependencyProperty。