我正在尝试使用Silverlight 3在ItemsControl DataTemplate中设置Canvas属性。根据this post,唯一的方法是使用ItemsContainerStyle为ContentPresenter类型设置它,因为仅限Canvas属性对画布的直接儿童生效。这似乎在SL3中不起作用,因为ItemsControl没有ItemsContainerStyle属性,所以我尝试了this article建议的ListBox,但它仍然不起作用。从下面的XAML,我希望看到一个绿色方块,数字10,30,50,70从“NW”到“SE”方向连着。任何人都可以告诉我为什么他们都在NW角落里堆叠在一起吗?
<UserControl x:Class="TestControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:System="clr-namespace:System;assembly=mscorlib" >
<StackPanel>
<ListBox>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Background="Green" Width="100" Height="100" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding}" />
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding}" />
<Setter Property="Canvas.Top" Value="{Binding}" />
</Style>
</ListBox.ItemContainerStyle>
<ListBox.Items>
<System:Int32>10</System:Int32>
<System:Int32>30</System:Int32>
<System:Int32>50</System:Int32>
<System:Int32>70</System:Int32>
</ListBox.Items>
</ListBox>
</StackPanel>
</UserControl>
答案 0 :(得分:7)
我不确定它是否适用于您的场景,但我过去使用RenderTransform完成了这项工作。
<ItemsControl>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Background="Green" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding}">
<TextBox.RenderTransform>
<TranslateTransform X="100" Y="100" />
</TextBox.RenderTransform>
</TextBox>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.Items>
<System:Int32>10</System:Int32>
<System:Int32>30</System:Int32>
<System:Int32>50</System:Int32>
<System:Int32>70</System:Int32>
</ItemsControl.Items>
</ItemsControl>
或者在绑定的情况下,您需要使用转换器
<ItemsControl>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Background="Green" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding}" RenderTransform="{Binding Converter={StaticResource NumberToTransformGroupConverter}}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.Items>
<System:Int32>10</System:Int32>
<System:Int32>30</System:Int32>
<System:Int32>50</System:Int32>
<System:Int32>70</System:Int32>
</ItemsControl.Items>
</ItemsControl>
public void ConvertTo(object value, ...)
{
int intValue = int.Parse(value.ToString());
return new TransformGroup()
{
Children = new TransformCollection()
{
new TranslateTransform { X = intValue, Y = intValue }
}
};
}
答案 1 :(得分:3)
Silverlight4不会绑定到样式中的附加属性。我建议使用David Anson描述的here方法。
<UserControl.Resources>
<Style x:Key="ScreenBindStyle" TargetType="ListBoxItem">
<Setter Property="Helpers:SetterValueBindingHelper.PropertyBinding">
<Setter.Value>
<Helpers:SetterValueBindingHelper>
<Helpers:SetterValueBindingHelper Type="Canvas" Property="Left" Binding="{Binding LocationField.Value.X}" />
<Helpers:SetterValueBindingHelper Type="Canvas" Property="Top" Binding="{Binding LocationField.Value.Y}" />
<Helpers:SetterValueBindingHelper Type="Canvas" Property="ZIndex" Binding="{Binding ZIndex.Value}" />
</Helpers:SetterValueBindingHelper>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<ContentPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
在列表框中:
ItemContainerStyle="{StaticResource ScreenBindStyle}"
答案 2 :(得分:2)
旧帖但我遇到了同样的问题,但现在使用SL5,现在允许样式设置器中的Binding
。我试图避免使用ListBox
(因为它处理选择等),而ItemsControl
仍然没有ItemContainerStyle
。所以我尝试了一些事情。
我没有找到很多讨论这个问题的主题,所以让我分享我的解决方案(对不起,如果它重复)
事实上,通过在Style
资源中添加未命名的ItemsControl
,我找到了一种非常方便的方法来解决问题:
<ItemsControl ItemsSource="{Binding Path=MyData}">
<ItemsControl.Resources>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Top" Value="{Binding Path=Bounds.Top}"/>
<Setter Property="Canvas.Left" Value="{Binding Path=Bounds.Left}"/>
<Setter Property="Width" Value="{Binding Path=Bounds.Width}"/>
<Setter Property="Height" Value="{Binding Path=Bounds.Height}"/>
</Style>
</ItemsControl.Resources>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="my:DataType">
...
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
像SL5中的魅力一样:)
答案 3 :(得分:0)
我无法解释你所看到的。你的Xaml至少在几个方面被打破了。
首先,Xaml本身失败,因为: -
<Style TargetType="ContentPresenter">
应该是
<Style TargetType="ContentControl">
ListBox
案例中的项容器类型为ListBoxItem
,派生自ContentControl
。
仍然没有这样,在样式设置器中放置{Binding}仍然不起作用。我想你想象的是,样式将依次应用于每个项目并从当前项目中获取其值。但是,即使绑定在样式中工作,也只有一个样式,它将从ListBox DataContext
获取其数据绑定。这是一个不同的DataContext
,适用于每个ListBox项(在本例中是Items集合中的每个Item)。
我仍然认为Ben有一个合理的解决方案可以消除这种方法。