【问题标题】:Caliburn Micro - Display a name on a tab control - Beginner issueCaliburn Micro - 在选项卡控件上显示名称 - 初学者问题
【发布时间】:2020-03-25 20:22:57
【问题描述】:

参考文献

Github 项目CMTabNavigation

TargetFramework netcoreapp3.0

PackageReference Caliburn.Micro Version="4.0.105-alpha"

当用户单击菜单项时,我正在做我的第一个示例以在选项卡控件中显示 ViewModel。 该示例工作正常,但选项卡上的显示名称不起作用。你能帮我吗

<Window x:Class="CMTabNav.Views.ShellView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:cal="http://www.caliburnproject.org"
        xmlns:local="clr-namespace:CMTabNav.Views"
        mc:Ignorable="d"
        Title="ShellView" Height="450" Width="800">
    <DockPanel>
        <Menu DockPanel.Dock="Top" FontSize="25">
            <MenuItem Header="_File">
                <MenuItem.Background>
                    <RadialGradientBrush>
                        <GradientStop Color="Black" Offset="0"/>
                        <GradientStop Color="#FFC3C1AD" Offset="0.105"/>
                    </RadialGradientBrush>
                </MenuItem.Background>
                <MenuItem x:Name="PartsList" Header="_Parts List" />
                <MenuItem x:Name="AssembliesList" Header="_Assembly List" />
                <MenuItem x:Name="Demo" Header="_Demo" />
                <MenuItem x:Name="ExitApplication" Header="_Exit" />
            </MenuItem>

        </Menu>
        <Grid>
            <TabControl x:Name="Items">
                <TabControl.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="{Binding DisplayName}" />
                            <Button Content="X"  
                                cal:Message.Attach="DeactivateItemAndTryClose($dataContext, 'true')" />

                        </StackPanel>

                    </DataTemplate>
                </TabControl.ItemTemplate>
            </TabControl>


            <!--<ContentControl x:Name="ActiveItem" Margin="20 5 20 20">

            </ContentControl>-->
        </Grid>
    </DockPanel>
</Window>

ShellViewModel.cs

using Caliburn.Micro;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace CMTabNav.ViewModels
{
    public class ShellViewModel : Conductor<object>.Collection.OneActive
    {
        public ShellViewModel()
        {

        }

        public void PartsList()
        {

            ActivateItemAsync(IoC.Get<PartsListViewModel>(), new CancellationToken());
             DisplayName = "Part List";

        }
        public void AssembliesList() //AssembliesList
        {
            ActivateItemAsync(IoC.Get<AssembliesListViewModel>(), new CancellationToken());
            DisplayName = "Assembly List";
        }
        public void Demo()
        {
            ActivateItemAsync(IoC.Get<DemoViewModel>(), new CancellationToken());
            DisplayName = "Demo View";
        }
        public async Task DeactivateItemAndTryClose(IScreen item, bool close)
        {
            await DeactivateItemAsync(item, close, new CancellationToken());
        }


    }
}

PartsListViewModel.cs

using Caliburn.Micro;
using System;
using System.Collections.Generic;
using System.Text;

namespace CMTabNav.ViewModels
{
    class PartsListViewModel: Screen
    {
    }
}

【问题讨论】:

  • 为什么要从Screen类继承VM?
  • 我还没有答案,因为我正处于一个巨大的学习过程中。我确实基于 youtube 上的 Tim Corey 课程“TimCo 零售管理”构建了这个示例。抱歉,我还没有掌握该课程的所有内容。

标签: c# wpf xaml caliburn.micro


【解决方案1】:

您可以更改视图模型以继承PropertyChangedBase 类并实现IHaveDisplayName 接口,如下所示

class PartsListViewModel : PropertyChangedBase, IHaveDisplayName
{
    public string DisplayName { get; set; }
}

根据您的数据模板,DisplayName 应在选项卡项本身的数据上下文中声明(PartsListViewModelDemoViewModel 等),而不是在ShellViewModel。您应该在激活任何视图模型之前设置显示名称

public void PartsList()
{
    var partsListViewModel = IoC.Get<PartsListViewModel>();
    partsListViewModel.DisplayName = "Part List";
    ActivateItemAsync(partsListViewModel, new CancellationToken());
}

您还应该更新DeactivateItemAndTryClose 方法并传递不同的类型参数而不是IScreen

public async Task DeactivateItemAndTryClose(PropertyChangedBase item, bool close)
{
    await DeactivateItemAsync(item, close, new CancellationToken());
}

但是,您可以保留视图模型,继承 Screen 类,只在激活之前为每个视图模型正确设置 DisplayName,如上面的 PartsList() 方法所示

【讨论】:

  • 感谢您的意见。以后会看的
  • 继承 PropertyChangedBase 类并在所有 ViewModel 上实现 IHaveDisplayName 的建议更改工作正常。谢谢帕维尔。继承的 Screen 类解决方案还没有工作。我需要看看为什么。最好的问候
猜你喜欢
  • 2014-07-17
  • 2018-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-23
相关资源
最近更新 更多