问题 如何在Silverlight 3中将Canvas用作ItemsConnel的ItemsPanel


我试图使用Silverlight 3在ItemsControl DataTemplate中设置Canvas属性 这个帖子,这样做的唯一方法是使用ItemsContainerStyle为ContentPresenter类型设置它,因为Canvas属性仅对Canvas的直接子项生效。这似乎不适用于SL3,因为ItemsControl没有ItemsContainerStyle属性,所以我按照建议尝试了一个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>

3274
2018-03-05 00:56


起源

谢谢skb,这回答了我的问题,这是如何在WPF中执行此操作:-)正如您所说,它在WPF中运行良好。 - MikeKulls


答案:


我不确定它是否适用于您的场景,但我在过去使用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 }
        }
    };
}

7
2018-03-05 01:18



+1在提供的场景中,这很有效。把它放在ScrollViewer或Stackpanel中,这个问题开始浮出水面。但是你唯一能做的就是全力以赴并编写一个自定义面板,以便在测量和排列阶段提供所需的行为。 - AnthonyWJones


Silverlight4不会绑定到样式中的附加属性。我建议使用David Anson描述的方法 这里

    <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}"

3
2018-02-15 18:12





老帖子,但我遇到了同样的问题,但现在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中的魅力一样工作:)


2
2018-04-22 17:37





我无法解释你所看到的。你的Xaml至少在几个方面被破坏了。

首先,Xaml本身失败了,因为: -

<Style TargetType="ContentPresenter">

应该

<Style TargetType="ContentControl">

在案件中的物品容器 ListBox 是类型的 ListBoxItem 它来源于 ContentControl

仍然没有这样,在样式设置器中放置{Binding}仍然不起作用。我想你是想象风格将依次应用于每个项目并从当前项目中获取其值。然而,即使绑定工作的风格,只会有  样式,它将从ListBox获取其数据绑定 DataContext。这是一个不同的 DataContext 适用于每个ListBox项目(在本例中是Items集合中的每个Item)。

我仍然认为Ben有一个合理的解决方案可以消除这种方法。


0
2018-03-05 18:14



嗨,安东尼我可能会误读你的答案,但从我所知道的几乎所有你在这里写的都是真空的。首先,xaml不会因为目标类型而失败,实际上如果你做出你建议的更改,它就会失败。其次,风格中的绑定确实有效。第三,绑定不从列表框中获取其上下文,而是从列表框项中获取它。至于只有一种风格,我怀疑风格被克隆。这里重要的是在开始DOES工作时呈现的解决方案,我在WPF中使用它,它只是在Silverlight中不起作用。 - MikeKulls
@MikeKulls:是的,你误解了我;)。让我从第二个反对意见开始,因为这是误解的真正根源。我声明“将{Binding}放置在样式设置器中 不 工作“和”甚至 如果 从那时起它的所有假设因为你说它不起作用。假设在那时解决了绑定 Value 风格的属性将受此限制 共同 价值(N.B. 不 绑定本身)并将用于所有项目。最后甚至 如果 其他一切都在TargetType上运行 是 不正确。 - AnthonyWJones
但解决方案确实有效(我说它在哪里不起作用?),绑定在样式中起作用。我正在使用这个解决方案几乎作为生产应用程序中的副本过去,我可以说它最肯定是有效的。请记住,skb声明解决方案适用于WPF,而不是在Silverlight中。 - MikeKulls