我有点惊讶的是,无法通过XAML为Canvas.Children设置绑定.我不得不采用代码隐藏方法,看起来像这样:
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
DesignerViewModel dvm = this.DataContext as DesignerViewModel;
dvm.Document.Items.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Items_CollectionChanged);
foreach (UIElement element in dvm.Document.Items)
designerCanvas.Children.Add(element);
}
private void Items_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
ObservableCollection<UIElement> collection = sender as ObservableCollection<UIElement>;
foreach (UIElement element in collection)
if (!designerCanvas.Children.Contains(element))
designerCanvas.Children.Add(element);
List<UIElement> removeList = new List<UIElement>();
foreach (UIElement element in designerCanvas.Children)
if (!collection.Contains(element))
removeList.Add(element);
foreach (UIElement element in removeList)
designerCanvas.Children.Remove(element);
}
Run Code Online (Sandbox Code Playgroud)
我更喜欢在XAML中设置一个绑定,如下所示:
<Canvas x:Name="designerCanvas"
Children="{Binding Document.Items}"
Width="{Binding Document.Width}"
Height="{Binding Document.Height}">
</Canvas>
Run Code Online (Sandbox Code Playgroud)
有没有办法在不采用代码隐藏方法的情况下实现这一目标?我已经完成了一些关于这个主题的谷歌搜索,但是对于这个具体问题还没有提出太多.
我不喜欢我当前的方法,因为它通过使View知道它的ViewModel来破坏我的漂亮的Model-View-ViewModel.
我目前正在尝试使用ItemsControl将一组对象绑定到Silverlight 3中的Canvas,如下所示:
<ItemsControl x:Name="ctrl" ItemsSource="{Binding myObjectsCollection}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas></Canvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Rectangle Stroke="LightGray" Fill="Black" StrokeThickness="2"
RadiusX="15" RadiusY="15" Canvas.Left="{Binding XAxis}"
Height="25" Width="25">
</Rectangle>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Run Code Online (Sandbox Code Playgroud)
不幸的是,似乎Canvas.Left上的绑定被忽略了.根据我在这里学到的东西,这似乎是由于项目被放置在内容展示器内而不是我在项目面板中指定的实际画布.
有没有办法可以使用数据绑定来确定画布上元素的位置?