【问题标题】:WPF/MVVM Load same UserControl multiple times in tab controlWPF/MVVM 在选项卡控件中多次加载相同的 UserControl
【发布时间】:2019-12-25 15:23:42
【问题描述】:

我对 WPF/MVVM 还是很陌生,还有很多东西要学,但我现在遇到了一个问题,我似乎无法找到好的答案。很可能是因为我问错了问题。

我有什么: 我有一个带有一些加载用户控件的按钮的主窗体。其中一个用户控件包含一个 TabControl。

这个 TabControl 有一个手动填充的第一个选项卡,我已经从下面的 sn-p 中排除了它,但所有其他选项卡都应该填充另一个用户控件,它将根据其视图模型构造函数加载数据库数据。

XAML:

             <TabItem Header="Two" 
                     Name="Two" 
                     HorizontalAlignment="Stretch" 
                     VerticalAlignment="Stretch"
                <ContentControl cal:View.Model="{Binding LoadedControl}"></ContentControl>
            </TabItem>

            <TabItem Header="Three" 
                     HorizontalAlignment="Stretch" 
                     VerticalAlignment="Stretch"
               <ContentControl cal:View.Model="{Binding LoadedControl}"></ContentControl>
            </TabItem>
            <TabItem Header="Four" 
                     HorizontalAlignment="Stretch" 
                     VerticalAlignment="Stretch"
               <ContentControl cal:View.Model="{Binding LoadedControl}"></ContentControl>
            </TabItem>

C#


        private DocumentTemplateControlViewModel _loadedControl;

        public DocumentTemplateControlViewModel LoadedControl
        {
            get { return _loadedControl; }
            set
            {
                if (value == _loadedControl)
                    return;

                _loadedControl = value;
                NotifyOfPropertyChange(() => LoadedControl);
            }
        }


        public int SelectedTabIndex
        {
            get
            {
                return _selectedTabIndex;
            }
            set
            {

                Task.Run(() => LoadData());
                _selectedTabIndex = value;
                LoadedControl = new DocumentTemplateControlViewModel(Templates, _selectedTabIndex);
             }

现在,这可以正常工作,因为我希望它适用于选项卡二,但如果我添加同一行

<ContentControl cal:View.Model="{Binding LoadedControl}">

到选项卡三、四等。(正如我在上面的 XAML sn-p 中所做的那样)它只会在我添加绑定的最后一个选项卡上工作,而选项卡二、三将是空白。

我也尝试使用 Caliburn Micro ActivateItem 实现相同的目的,但这意味着我也只能在 TabControl XAML 中声明一个 ActiveItem。

TLDR:在 tabitem 中动态显示新用户控件视图模型的最佳方式是什么?

非常感谢

【问题讨论】:

  • 一个特定的 UI 元素只能出现一次,但为什么要在多个选项卡中显示相同的内容? LoadedControl 属性只有一个,不是吗?
  • 嘿 mm8,用户控件上有一些项目,例如列表框和动态网格,它由数据库中的数据填充。就我而言,选项卡是模板选项。根据选择,将在用户控件中填充的数据会有所不同,但实际的用户控件应该是相同的,只是数据不同。目前只有一个 LoadedControl,因为我不知道还有什么其他方法可以接近它。我可以创建一个 LoadedControl2,3,4,5 并将它们绑定到其他选项卡,但必须有一种更简洁的方法来实现这一点
  • 那么为什么不从视图模型的Items 属性返回IEnumerable&lt;DocumentTemplateControlViewModel&gt; 并使用ContentTemplate?你如何初始化LoadedControl
  • 可能是因为我不熟悉 ContentTemplate 并且无法弄清楚如何在我的案例中应用它。 LoadedControl 目前仅根据上面的 C# sn-p 在选项卡索引更改时初始化
  • 如果我按照你想要做的正确。我可能会构建一个用户控件来封装 UI。为此定义一个视图模型。通过 datatype= 将作为用户控件的数据模板关联到 viewmodel 类型。然后,当您通过 itemssource 呈现其中一个视图模型时,您将其作为用户控件的数据上下文。这是一个相当标准的视图模型优先模式。数据模板可以在范围内的任何资源中。应用程序、窗口、tabcontrol....任何适合的。

标签: wpf mvvm user-controls caliburn.micro tabitem


【解决方案1】:

Conductor&lt;IScreen&gt;.Collection.OneActive 派生您的视图模型,并将要绑定到选项卡的DocumentTemplateControlViewModel 对象添加到Items 属性:

public class ShellViewModel : Conductor<IScreen>.Collection.OneActive
{
    public ShellViewModel()
    {
        Items.Add(new DocumentTemplateControlViewModel { DisplayName = "1" });
        Items.Add(new DocumentTemplateControlViewModel { DisplayName = "2" });
        Items.Add(new DocumentTemplateControlViewModel { DisplayName = "3" });
    }
}

DocumentTemplateControlViewModel 必须实现 IScreen,最简单的方法是从 Screen 派生:

public class DocumentTemplateControlViewModel : Screen
{
}

然后,您可以在 XAML 中简单地添加 TabControlContentTemplate,例如:

<TabControl Name="Items">
    <TabControl.ContentTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding DisplayName}" />
        </DataTemplate>
    </TabControl.ContentTemplate>
</TabControl>

您可以将 TextBlock 替换为 UserControl 或任何其他 UI 元素。

【讨论】:

  • 您好 mm8,谢谢。我试图让这个逻辑工作一段时间,但我必须承认我并没有走得太远。虽然我认为我可能错误地设置了 Usercontrol 数据模板。此外,我的选项卡控件的第一个选项卡看起来与模板完全不同,有什么好的方法吗?
  • @JoranStoops:这个例子你在哪里失败了?您可以将其复制并粘贴到您的解决方案中。
猜你喜欢
  • 2013-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多