【问题标题】:MVVM, ViewModelLocator, dynamically show View with ViewModel based on propertyMVVM,ViewModelLocator,基于属性动态展示View和ViewModel
【发布时间】:2013-12-19 22:44:54
【问题描述】:

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

我有一个包含 TileUserControl 的 View 和 ViewModel。 它需要一组图块,并以定义的大小、颜色、顺序等显示它们。它还能够将故事分组,并允许用户添加和删除 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; }

    }

到目前为止一切都很好。一切正常。

所有图块都有内容。我想将内容设置为Tile Object上View字符串对应的View和ViewModel。

我正在使用 MVVM Light,但也可能使用 Caliburn Mico。 瓦片控件是 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>

我的问题是如何将 UserControl 从 Tile.View 加载到 Tile 内容中。 我对 DataTrigger 和 DataTemplate 感到满意。

StringToTileConverter 只是返回 ViewModel 的名称。

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

而且所有这些代码都不是很干净,所以我问是否有人有更干净的方法来做到这一点。

【问题讨论】:

  • 漂亮的图画 :) 你试过什么吗?你能发布你到目前为止得到的东西,还是你要求我们为你做这件事? :)
  • 对不起,但我认为我不明白这正是问题所在...您是在寻求有关 MVVM 框架的建议以实现此设计吗?
  • :-) 目前我的一切都以静态方式工作。这意味着我已经为 30 个图块定义了所有图块和内容控件。但我想让用户可以选择他/她需要的瓷砖。因此我引入了 Tile 对象和 BindableCollection 集合。但我无法再次“连接”一些东西。
  • 确保检查 DataTemplateSelector。您可以创建所需的任何逻辑来为每个 Tile 对象返回正确的视图。
  • “我的问题是如何将 UserControl 从 Tile.View 加载到 Tile 内容中”是什么意思。 ???你能把这个问题分开并准确解释你想要做什么吗?什么tile.view加载???什么是磁贴内容??什么是“得到”?得到它的参考?把它移到别的地方?你什么意思?

标签: c# wpf mvvm ivalueconverter viewmodellocator


【解决方案1】:

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

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

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

如果您需要更完整的示例,请告诉我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-21
    • 1970-01-01
    • 2012-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多