Silverlight 5 隐式数据模板和 ContentPresenter 绑定 MVVM



所以我有一个可能有多种类型的对象的集合。例如,具有 B 的基类和后代 C,D,E。

所有这些都将在 ItemsControl 中,但是具有自定义(以某种方式随机)逻辑。因此,我在 XAML 中创建了一个 ItemsControl,指定将它们绑定到类型的 DataTemplates,并让 Silverlight 隐式数据模板引擎处理其余部分。

元素在 ItemsControl 表示器中的位置在某种程度上是随机的,并且仅在运行时作为元素本身(基类的一部分)中的依赖项属性提供。

我的问题是,默认情况下,ItemsControl 将项目包装在 ContentPresenter 对象中,因此在数据模板中设置 Canvas.Left 和 Canvas.Top 不起作用。因为这应该在内容演示器级别设置。但是,如果我定义 ContentPresenter 样式,则其数据源是 ItemsControl 本身,而不是项。因此,我不能以这种方式绑定项目的位置。

任何想法,如何将项目位置属性绑定到 ContentPresenters Canvas.Left 属性?

在代码方面:

<ItemsControl HorizontalAlignment="Stretch" Grid.Row="0" Grid.ColumnSpan="3"
                  x:Name="CardItems" ItemsSource="{Binding CardList}" ScrollViewer.HorizontalScrollBarVisibility="Disabled"
                  ScrollViewer.VerticalScrollBarVisibility="Disabled">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="SizeChanged">
                <ei:CallMethodAction MethodName="WndSizeChanged" TargetObject="{Binding}" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>
<UserControl.Resources>
    <DataTemplate DataType="Card:AdCardViewModel">
        <Canvas d:DesignHeight="300" d:DesignWidth="150" Width="{Binding CardSize.Width}" Height="{Binding CardSize.Height}" Background="Red">
            <Canvas.Projection>
                <PlaneProjection RotationY="{Binding Path=Rotation}"/>
            </Canvas.Projection>
            <Viewbox>
                <StackPanel>
                    <StackPanel.Background>
                        <SolidColorBrush Color="{StaticResource OriginalRecommendationColor}"/>
                    </StackPanel.Background>
                    <TextBlock Text="{Binding AdCard}" Foreground="CadetBlue"/>
                </StackPanel>
            </Viewbox>
        </Canvas>
    </DataTemplate>
</UserControl.Resources>

附言。我使用的是 MVVM Light,所以我宁愿避免使用隐藏文件的代码。

乐:

这似乎有效,但是由于某种原因,Visual Studio Intellisense对此没有想法。运行时似乎还可以,但是在设计时什么都没有。任何想法,如何使所有这些在 Blend 中也能正常工作?

          <ItemsControl.Resources>
            <Style TargetType="ContentPresenter">
                <Setter Property="Canvas.Left"  Value="{Binding  Path=Position.Height}"/>
                <Setter Property="Canvas.Top"  Value="{Binding  Path=Position.Width}"/>
                <Setter Property="Width" Value="Auto"/>
                <Setter Property="Height" Value="Auto"/>
                <Setter Property="HorizontalAlignment" Value="Stretch"/>
                <Setter Property="VerticalAlignment" Value="Stretch"/>
            </Style>
        </ItemsControl.Resources>

视图模型定位器:

    static ViewModelLocator()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
        // Step #1 - Register the data providing services, design and runtime versions
        if (ViewModelBase.IsInDesignModeStatic)
        {
            SimpleIoc.Default.Register<ICardService, DesignCardService>();
        }
        else
        {
            SimpleIoc.Default.Register<ICardService, CardService>();
        }
        // Step#2 Register the ViewModels
        SimpleIoc.Default.Register<CardSlideShowViewModel>();
    }

    /// <summary>
    ///     Gets the Video property.
    /// </summary>
    [SuppressMessage("Microsoft.Performance",
        "CA1822:MarkMembersAsStatic",
        Justification = "This non-static member is needed for data binding purposes.")]
    public CardSlideShowViewModel CardSlideShowSlideShow
    {
        get { return ServiceLocator.Current.GetInstance<CardSlideShowViewModel>(); }
    }

谢谢

设计时视图模型应该可以解决问题。只需创建运行时 vm 的简单表示形式 - 在其构造函数中初始化 CardViewModel 集合。

然后,在设计时绑定视图模型,如下所示:

<UserControl x:Class="MyView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         d:DataContext="{d:DesignInstance local:MyViewModel,
                                          IsDesignTimeCreatable=True}"

好吧,不是真正的答案,但是我最接近这个。在我看来,VS 2010 还不支持此功能。但是它在VS 2012中有效。因此,如果您可以进行升级。

最新更新