从ViewModel动态添加UserControl到View

时间:2015-01-12 15:06:55

标签: wpf mvvm

我有一个View只是一个ListBox或ItemsControl(试过两个)我试图从ViewModel向ListBox添加多个usercontrol实例。我正在尝试这个:

我在Main ViewModel中有一个UserControl ViewModel的ObservableCollection。

<Controls:MetroWindow.Resources>
  <DataTemplate x:Key="{x:Type local2:TorrentControlViewModel}">
        <local:TorrentControl />
    </DataTemplate>

  <ItemsControl ItemsSource="{Binding TorrentControlViewModels}"  VerticalAlignment="Top">

我得到的只是ListBox中的一个字符串: Namespace.ViewModels.TorrentControlViewModel

Binding似乎有效,但UserControl从未初始化。 我需要在列表框中添加未知数量的这些控件。

(WPF MVVM) How to add a user control to a View from a collection in a ViewModel

控制

<UserControl x:Class="Music.Views.TorrentControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:local="clr-namespace:Music"
         xmlns:converters="clr-namespace:Music.Converters"
         xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
         xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
         xmlns:behaviors="clr-namespace:Music.Behaviors"
         mc:Ignorable="d" d:DesignWidth="900" Height="300" Width="Auto">
<UserControl.Resources>
    <Style x:Key="ButtonHype" TargetType="{x:Type Hyperlink}">
        <Setter Property="TextDecorations" Value="None" />
    </Style>
    <converters:BoolToVisibilityConverter x:Key="BoolToVisConverter" />
    <converters:ReverseBooleanConverter x:Key="ReverseBooleanConverter" />
    <Style x:Key="ListBoxItemStyle1" TargetType="{x:Type ListBoxItem}">
        <Setter Property="Background" Value="Transparent" />
        <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment,
        RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
        <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment,
         RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
        <Setter Property="Padding" Value="2,0,0,0" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListBoxItem}">
                    <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"
                        Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
                        <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                        SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                        VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsSelected" Value="true">
                            <Setter Property="Background" Value="Transparent" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</UserControl.Resources>
<Grid VerticalAlignment="Top" Width="Auto" Height="Auto" MinWidth="400" x:Name="MainGrid">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>

    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" MaxHeight="40" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="100" />
        <!--<RowDefinition Height="Auto" />-->
        <!--<RowDefinition Height="Auto" />-->
    </Grid.RowDefinitions>

    <Image HorizontalAlignment="Center"  Grid.Row="0" Grid.Column="0"
        Source="{Binding RootSource}" RenderOptions.BitmapScalingMode="HighQuality" Height="30"
        Margin="10,0,10,0" Stretch="Uniform"
        RenderTransformOrigin=".5,.5" Cursor="Hand" VerticalAlignment="Center">
        <Image.RenderTransform>
            <RotateTransform x:Name="AnimatedRotateTransform" Angle="0" />
        </Image.RenderTransform>
        <Image.Triggers>
            <EventTrigger RoutedEvent="FrameworkElement.Loaded">
                <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetName="AnimatedRotateTransform"
                            Storyboard.TargetProperty="Angle"
                            By="0"
                            To="360"
                            Duration="0:0:0.3"
                            RepeatBehavior="2x"
                            FillBehavior="Stop" />
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </Image.Triggers>
    </Image>
    <!--<Viewbox Stretch="UniformToFill" StretchDirection="Both" Grid.Row="0" Grid.Column="1">-->
    <TextBlock x:Name="TorrentNameText" HorizontalAlignment="Left"  Grid.Row="0" Grid.Column="1"
        Text="{Binding TorrentName}" VerticalAlignment="Center" Grid.ColumnSpan="1"
        Margin="4,-5,0,0" TextTrimming="CharacterEllipsis"
        FontSize="26" Width="Auto" Foreground="White">

        <TextBlock.Triggers>
            <EventTrigger RoutedEvent="FrameworkElement.Loaded">
                <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimation
                            Storyboard.TargetName="TorrentNameText"
                            Storyboard.TargetProperty="(UIElement.Opacity)"
                            From="0.0" To="1" Duration="0:0:4"
                            AutoReverse="False" RepeatBehavior="1x" />
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </TextBlock.Triggers>
    </TextBlock>
    <!--</Viewbox>-->
    <!--<Rectangle x:Name="LineRect" Height="2"  VerticalAlignment="Bottom" Fill="Gray" Grid.Row="2" Grid.RowSpan="3"
                       Margin="-1000,0,0,0" Grid.Column="2" Grid.ColumnSpan="2" Visibility="Collapsed">
    </Rectangle>-->

    <Border x:Name="CDImageBorder" BorderBrush="#F80271" BorderThickness="2" Grid.Row="0" Grid.Column="2"
            MaxHeight="175" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.RowSpan="3"
            Width="Auto"
            Margin="44,0,0,0" Visibility="Visible">
        <Border.Effect>
            <DropShadowEffect Opacity="50" Color="#FF9933" BlurRadius="10" />
        </Border.Effect>
        <Image x:Name="CDImage" Grid.Row="0" Grid.Column="3"
            RenderOptions.BitmapScalingMode="HighQuality" Height="175"
            Stretch="Uniform" HorizontalAlignment="Left" Margin="0,0,0,0"
            RenderTransformOrigin=".5,.5" VerticalAlignment="Top" Grid.RowSpan="3"
           Source="{Binding CDImageSource}" Visibility="Visible" />
    </Border>
    <Controls:ProgressRing x:Name="ProgressRing" Grid.Row="0" Grid.Column="2" Height="38" Width="40"
                           IsActive="{Binding IsWorking}" Foreground="#F80271" Margin="30,4,0,0" HorizontalAlignment="Left" />

    <ListBox Grid.Row="2" Grid.Column="1" Width="Auto"
             Margin="0 0 0 0" ScrollViewer.VerticalScrollBarVisibility="Auto" Height="Auto"
              ItemContainerStyle="{DynamicResource ListBoxItemStyle1}" ItemsSource="{Binding SubDirectories}">
        <i:Interaction.Behaviors>
            <behaviors:ScrollIntoViewBehavior />
        </i:Interaction.Behaviors>
        <ListBox.Style>
            <Style TargetType="{x:Type ItemsControl}">
                <Style.Resources>
                    <Style TargetType="{x:Type ListBoxItem}">
                        <Setter Property="FocusVisualStyle" Value="{x:Null}" />
                        <Setter Property="Background" Value="Transparent" />
                        <Setter Property="BorderBrush" Value="Transparent" />
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="{x:Type ListBoxItem}">
                                    <Grid Margin="0,0,0,0">
                                        <Border Background="{TemplateBinding Background}"
                                            BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1"
                                            SnapsToDevicePixels="True" />
                                        <ContentPresenter Margin="8,5" />
                                    </Grid>
                                    <ControlTemplate.Triggers>
                                        <MultiTrigger>
                                            <MultiTrigger.Conditions>
                                                <Condition Property="IsMouseOver" Value="True" />
                                            </MultiTrigger.Conditions>
                                            <Setter Property="Background" Value="#F80271" />
                                            <Setter Property="BorderBrush" Value="Black" />
                                        </MultiTrigger>
                                    </ControlTemplate.Triggers>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </Style.Resources>

                <Setter Property="Background" Value="Transparent" />
                <Setter Property="BorderThickness" Value="0" />
                <Setter Property="ItemsPanel">
                    <Setter.Value>
                        <ItemsPanelTemplate>
                            <StackPanel>
                                <i:Interaction.Behaviors>
                                    <ei:FluidMoveBehavior AppliesTo="Children" Duration="00:00:00.3">
                                        <ei:FluidMoveBehavior.EaseX>
                                            <CircleEase EasingMode="EaseOut" />
                                        </ei:FluidMoveBehavior.EaseX>
                                    </ei:FluidMoveBehavior>
                                </i:Interaction.Behaviors>
                            </StackPanel>
                        </ItemsPanelTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ListBox.Style>
        <!--<ListBoxItem>
            </ListBoxItem>-->
    </ListBox>
    <StackPanel Grid.Column="1" Grid.Row="1" Background="Transparent" Height="Auto" Width="Auto"
               Grid.ColumnSpan="1" Orientation="Horizontal" Margin="10,0,0,0"/>
    <Grid  Width="Auto" Grid.Column="1" Grid.Row="1" Margin="5,0,0,0">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <Image  Grid.Row="0" Grid.Column="0"
            RenderOptions.BitmapScalingMode="HighQuality" Height="25" ToolTip="Torrent Complete"
            Stretch="Uniform" HorizontalAlignment="Left" Margin="0,0,0,0"
            RenderTransformOrigin=".5,.5" VerticalAlignment="Center"
            Visibility="Visible" Source="{Binding CheckSource}"/>
        <TextBlock DockPanel.Dock="Top"  Grid.Row="0" Grid.Column="1"><Hyperlink Command="{Binding UTorrentClientControlCommands}" Style="{StaticResource ButtonHype}"
                  CommandParameter="StartTorrent" ><InlineUIContainer>
                    <Image Source="{Binding StartSource}" VerticalAlignment="Center" Stretch="Uniform"
                        RenderOptions.BitmapScalingMode="HighQuality" RenderTransformOrigin=".5,.5"
                        ToolTip="Start Torrent" HorizontalAlignment="Center"
                        Margin="0,10,0,0" Height="32"  />
                </InlineUIContainer></Hyperlink></TextBlock>
        <TextBlock DockPanel.Dock="Top"  Grid.Row="0" Grid.Column="2"><Hyperlink Command="{Binding UTorrentClientControlCommands}" Style="{StaticResource ButtonHype}"
                  CommandParameter="StartTorrent" ><InlineUIContainer>
                    <Image Source="{Binding StartSource}" VerticalAlignment="Center" Stretch="Uniform"
                        RenderOptions.BitmapScalingMode="HighQuality" RenderTransformOrigin=".5,.5"
                        ToolTip="Start Torrent" HorizontalAlignment="Center"
                        Margin="0,10,0,0" Height="32"  />
                </InlineUIContainer></Hyperlink></TextBlock>
        <TextBlock DockPanel.Dock="Top"  Grid.Row="0" Grid.Column="3"><Hyperlink Command="{Binding UTorrentClientControlCommands}" Style="{StaticResource ButtonHype}"
                  CommandParameter="StartTorrent" ><InlineUIContainer>
                    <Image Source="{Binding StartSource}" VerticalAlignment="Center" Stretch="Uniform"
                        RenderOptions.BitmapScalingMode="HighQuality" RenderTransformOrigin=".5,.5"
                        ToolTip="Start Torrent" HorizontalAlignment="Center"
                        Margin="0,10,0,0" Height="32"  />
                </InlineUIContainer></Hyperlink></TextBlock>
        <TextBlock DockPanel.Dock="Top"  Grid.Row="0" Grid.Column="4"><Hyperlink Command="{Binding UTorrentClientControlCommands}" Style="{StaticResource ButtonHype}"
                  CommandParameter="StartTorrent" ><InlineUIContainer>
                    <Image Source="{Binding StartSource}" VerticalAlignment="Center" Stretch="Uniform"
                        RenderOptions.BitmapScalingMode="HighQuality" RenderTransformOrigin=".5,.5"
                        ToolTip="Start Torrent" HorizontalAlignment="Center"
                        Margin="0,10,0,0" Height="32"  />
                </InlineUIContainer></Hyperlink></TextBlock>
        <TextBlock DockPanel.Dock="Top"  Grid.Row="0" Grid.Column="5"><Hyperlink Command="{Binding UTorrentClientControlCommands}" Style="{StaticResource ButtonHype}"
                  CommandParameter="StartTorrent" ><InlineUIContainer>
                    <Image Source="{Binding StartSource}" VerticalAlignment="Center" Stretch="Uniform"
                        RenderOptions.BitmapScalingMode="HighQuality" RenderTransformOrigin=".5,.5"
                        ToolTip="Start Torrent" HorizontalAlignment="Center"
                        Margin="0,10,0,0" Height="32"  />
                </InlineUIContainer></Hyperlink></TextBlock>
        <TextBlock DockPanel.Dock="Top"  Grid.Row="0" Grid.Column="6"><Hyperlink Command="{Binding UTorrentClientControlCommands}" Style="{StaticResource ButtonHype}"
                  CommandParameter="StartTorrent" ><InlineUIContainer>
                    <Image Source="{Binding StartSource}" VerticalAlignment="Center" Stretch="Uniform"
                        RenderOptions.BitmapScalingMode="HighQuality" RenderTransformOrigin=".5,.5"
                        ToolTip="Start Torrent" HorizontalAlignment="Center"
                        Margin="0,10,0,0" Height="32"  />
                </InlineUIContainer></Hyperlink></TextBlock>
        <TextBlock DockPanel.Dock="Top"  Grid.Row="0" Grid.Column="7"><Hyperlink Command="{Binding UTorrentClientControlCommands}" Style="{StaticResource ButtonHype}"
                  CommandParameter="StartTorrent" ><InlineUIContainer>
                    <Image Source="{Binding StartSource}" VerticalAlignment="Center" Stretch="Uniform"
                        RenderOptions.BitmapScalingMode="HighQuality" RenderTransformOrigin=".5,.5"
                        ToolTip="Start Torrent" HorizontalAlignment="Center"
                        Margin="0,10,0,0" Height="32"  />
                </InlineUIContainer></Hyperlink></TextBlock>

    </Grid>

    <StackPanel />


</Grid>

1 个答案:

答案 0 :(得分:3)

您只需告诉Framework,您的DataTemplate适用于您指定的数据类型:

<DataTemplate DataType="{x:Type local2:TorrentControlViewModel}">
    <local:TorrentControl />
</DataTemplate>

现在,当它看到您的数据类型的对象时,它会找到DataTemplate(只要它在范围内声明)并呈现UserControl