How to use Canvas as the ItemsPanel for an ItemsControl in Silverlight 3

前端 未结 4 1934
闹比i
闹比i 2021-02-05 22:13

I am trying to set the Canvas properties in an ItemsControl DataTemplate with Silverlight 3. According to this post, the only way of doing that is to set it using the ItemsCont

相关标签:
4条回答
  • 2021-02-05 22:22

    Silverlight4 does not bind to attached properties in style. I suggest using David Anson's approach described 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>
    

    And in listbox:

    ItemContainerStyle="{StaticResource ScreenBindStyle}"
    
    0 讨论(0)
  • 2021-02-05 22:23

    I can't explain what you are seeing either. Your Xaml is broken in at least a couple of ways.

    First the Xaml itself fails because this:-

    <Style TargetType="ContentPresenter">
    

    should be

    <Style TargetType="ContentControl">
    

    the Item Containers in the case of ListBox are of type ListBoxItem which derive from ContentControl.

    Still without that the placing {Binding} in style setters still doesn't work. I guess you were imagining that the style would be applied to each item in turn and get its Value from the current item. However even if binding worked in the style, there would only be one style and it would get its data binding from the ListBox DataContext. This is a different DataContext that applies to each ListBox item (which in this case is each Item in the Items collection).

    Still I think Ben has a reasonable solution in place which eliminates this approach.

    0 讨论(0)
  • 2021-02-05 22:34

    Old post but I went into the same problem but now with SL5 that now allows Binding in style setters. I was trying to avoid to use the ListBox (because it handles selection and so on) and the ItemsControl still doesn't have an ItemContainerStyle. So I tried a few things.

    I haven't found many subject discussing this problem so let me share my solution (sorry if it duplicates)

    In fact, I found a very convenient way to solve the problem by adding an unnamed Style in the ItemsControl resources :

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

    Works like a charm in SL5 :)

    0 讨论(0)
  • 2021-02-05 22:42

    I'm not sure if it will work in your scenario, but I've accomplished this in the past using the 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>
    

    Or in the case of binding you will need to use a converter

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

    Converter

    public void ConvertTo(object value, ...)
    {
        int intValue = int.Parse(value.ToString());
    
        return new TransformGroup()
        {
            Children = new TransformCollection()
            {
                new TranslateTransform { X = intValue, Y = intValue }
            }
        };
    }
    
    0 讨论(0)
提交回复
热议问题