c# - MVVM、ViewModelLocator、根据属性动态显示View和ViewModel

标签 c# wpf mvvm ivalueconverter viewmodellocator

enter image description here我有一个设计问题。请查看所附图片以了解应用程序设计。 基本上我只需要帮助来找到正确的方法。

我有一个包含 TileUserControl 的 View 和 ViewModel。 它获取一组图 block ,并以定义的大小、颜色、顺序等显示它们。它还能够将故事分组,并允许用户添加和删除 Tiles。

Tile 对象如下所示。

    public class Tile
    {
        public int ID { get; set; }
        public string View { get; set; }
        public List<string> Views { get; set; }
        public string TileSize { get; set; }

    }

到目前为止一切顺利。一切正常。

所有图 block 都有内容。我想把内容设置到Tile Object上View字符串对应的View和ViewModel。

我正在使用 MVVM Light,但也可能使用 Caliburn Mico。 tiles 控件是用于 WPF 的 DevExpress TileLayoutControl。

DevExpress TileLayoutControl doc

编辑:使用 MainTilesView XAML 更新

    <Grid>

        <dxlc:TileLayoutControl Padding="60,41,0,0"
                                ItemsSource="{Binding Tiles}" 
                                ScrollBars="None" 
                                ScrollViewer.VerticalScrollBarVisibility="Hidden" 
                                AllowGroupHeaderEditing="False" 
                                AllowMaximizedElementMoving="True" Background="{x:Null}">

            <dxlc:TileLayoutControl.GroupHeaderStyle>
                <Style TargetType="dxlc:TileGroupHeader">
                    <Setter Property="Foreground" Value="White"/>
                    <Setter Property="FontSize" Value="24"/>
                    <Setter Property="FontFamily" Value="Segeo UI"/>
                    <Setter Property="FontWeight" Value="Light"/>
                </Style>
            </dxlc:TileLayoutControl.GroupHeaderStyle>

            <dxlc:TileLayoutControl.ItemTemplate>
                <DataTemplate>
                    <dxlc:Tile Header="{Binding Header}" 
                               Size="{Binding TileSize}" 
                               dxlc:TileLayoutControl.GroupHeader="{Binding GroupHeader}" 
                               Tag="{Binding ID}"  
                               dxlc:FlowLayoutControl.IsFlowBreak="{Binding IsNewGroup}" 
                               Background="{Binding BackgroundColor}">
                    </dxlc:Tile>
                </DataTemplate>
            </dxlc:TileLayoutControl.ItemTemplate>

            <dxlc:TileLayoutControl.Resources>
                <conv:IsUserControlConverter x:Key="IsUserControlConverter"/>
                <conv:StringToTileConverter x:Key="StringToTileConverter"/>
                <Style TargetType="{x:Type dxlc:Tile}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Path=TileSize}" Value="ExtraSmall">
                            <Setter Property="Size" Value="ExtraSmall"/>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding Path=TileSize}" Value="1x1">
                            <Setter Property="Size" Value="ExtraSmall"/>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding Path=TileSize}" Value="1x1">
                            <Setter Property="Size" Value="Small"/>
                            <Setter Property="Width" Value="150"/>
                            <Setter Property="Height" Value="150"/>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding Path=TileSize}"  Value="1x2">
                            <Setter Property="Size" Value="Large"/>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding Path=TileSize}"  Value="2x1">
                            <Setter Property="Size" Value="ExtraLarge"/>
                            <Setter Property="Width" Value="150"/>
                            <Setter Property="Height" Value="310"/>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding Path=TileSize}"  Value="2x2">
                            <Setter Property="Size" Value="ExtraLarge"/>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding Path=TileSize}"  Value="2x3">
                            <Setter Property="Size" Value="ExtraLarge"/>
                            <Setter Property="Width" Value="310"/>
                            <Setter Property="Height" Value="470"/>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding Path=TileSize}"  Value="3x2">
                            <Setter Property="Size" Value="ExtraLarge"/>
                            <Setter Property="Width" Value="470"/>
                            <Setter Property="Height" Value="310"/>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding Path=TileSize}"  Value="3x3">
                            <Setter Property="Size" Value="ExtraLarge"/>
                            <Setter Property="Width" Value="470"/>
                            <Setter Property="Height" Value="470"/>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding Path=TileSize}"  Value="4x2">
                            <Setter Property="Size" Value="ExtraLarge"/>
                            <Setter Property="Width" Value="630"/>
                            <Setter Property="Height" Value="310"/>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding Path=TileSize}"  Value="4x3">
                            <Setter Property="Size" Value="ExtraLarge"/>
                            <Setter Property="Width" Value="630"/>
                            <Setter Property="Height" Value="470"/>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding Path=TileSize}"  Value="4x4">
                            <Setter Property="Size" Value="ExtraLarge"/>
                            <Setter Property="Width" Value="630"/>
                            <Setter Property="Height" Value="630"/>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding Path=TileSize}"  Value="Single_1x1">
                            <Setter Property="Size" Value="Large"/>
                            <Setter Property="Width" Value="150"/>
                            <Setter Property="Height" Value="150"/>
                        </DataTrigger>



                        <DataTrigger Binding="{Binding Path=View,Converter={StaticResource IsUserControlConverter}}" Value="true">
                            <Setter Property="ContentTemplate">
                                <Setter.Value>
                                    <DataTemplate>
                                        <ContentControl cal:View.Model="{Binding Path=View, Converter={StaticResource StringToTileConverter}, UpdateSourceTrigger=Explicit}"/>                                        
                                    </DataTemplate>
                                </Setter.Value>
                            </Setter>
                        </DataTrigger>

                    </Style.Triggers>
                </Style>
            </dxlc:TileLayoutControl.Resources>

        </dxlc:TileLayoutControl>
    </Grid>

我的问题是如何将 Tile.View 中的 UserControl 加载到 Tile 内容中。 我在上面尝试了 DataTrigger 和 DataTemplate。

StringToTileConverter 仅返回 ViewModel 的名称。

目前使用 Caliburn Micro,我的绑定(bind)在模板部分之外工作正常,但我无法让它们与 DataTemplate 一起工作。

此外,所有这些代码都不是很干净,因此我想问问是否有人有更干净的方法来做到这一点。

最佳答案

当你使用 Caliburn.Micro ,您可以利用其内置的 ViewLocator。您不需要转换器或 DataTriggers,因为您可以按如下方式定义 DataTemplate:

  <DataTemplate>
    <ContentControl Width="100" Height="100" cal:View.Model="{Binding}" />
  </DataTemplate>

您可能会发现这有帮助:Binding ListBox to a collection of screens (widgets)

如果您需要更全面的示例,请告诉我。

关于c# - MVVM、ViewModelLocator、根据属性动态显示View和ViewModel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20358566/

相关文章:

c# - 输入 key 问题

wpf - 如何单向绑定(bind)到 materialDesign :ButtonProgressAssist. IsIndicatorVisible DependencyProperty

c# - Xamarin.Forms MVVM 从 DISplayAlert 获得响应

c# - WPF 针对 .NET 4.5 但 Windows 要求在应用程序运行时安装 .NET 3.5

c# - 如何格式化绑定(bind)的 wpf 数据网格文本列以不显示新的 DateTimes?

c# - 如何在具有相同目的的同一解决方案中为 C# 和 VB.NET 项目提供有意义的名称?

c# - WPF 图像源绑定(bind)有时有效有时无效

c# - 从基类列表返回引用返回 'nothing'

c# - 自定义 DataTemplate - 控件不占用完整的网格列宽

c# - 在 Caliburn.Micro 约定绑定(bind)文本框中自定义字符串格式