如何使用SoapBox将数据从View绑定到UserControl

问题描述 投票:0回答:2

我有我的 SoapBox.Document '注册'

[Export(SoapBox.Core.ExtensionPoints.Workbench.Documents, typeof(IDocument))]
[Export(CompositionPoints.Workbench.Documents.Register, typeof(Register))]
[Document(Name = DOC_NAME)]

class Register : AbstractDocument
{
    public Receipt actualReceipt;
    private const string DOC_NAME = "Register";
    public Register()
    {
        Name = DOC_NAME;
        Title = "Recipe Document Title";
        SomeProperty = "Hello from the recipe document!";
    }
}

在本文档中,我想使用 UserControls,它们是一种自己的“视图” 就像所有 ReceiptPositions 的 ListView

现在我得到了我的收据模型和收据位置

收据范本

class Receipt
{
    public int Id { get; set; }
    public string Receiptnumber { get; set; }
    public IList<ReceiptPositions> ReceiptPositions { get; set; }

和模型收据位置

class ReceiptPosition
{
    public int Id { get; set; }
    //public Receipt Receipt { get; set; } using for Database 
    public int Position { get; set; }
    public string Article { get; set; }
}

所以现在我想添加一个 UserControl 来显示 ReceiptPositions 中所有文章的列表。

但是如何绑定数据,以便当新的 ReceiptPosition 添加到 Receipt 中的 IList 时,UserControl 会自动“刷新”?

这是我需要的直观示例..

主机包含数据和两个插件,每个插件显示相同的数据,但以不同的方式。

c# wpf user-controls mef
2个回答
1
投票

您可以使用

ItemsControl
来实现此目的。

xaml:

<ItemsControl ItemsSource="{Binding MyReceipt.ReceiptPositions}">

    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <!-- Where you put your view -->
            <TextBox Text="{Binding Article}" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>

    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <!-- Can be whatever Panel type you want -->
            <StackPanel />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

</ItemsControl>

cs:

private Receipt _myReceipt;
public Receipt MyReceipt { get { return _myReceipt; } set { _myReceipt = value; OnPropertyChanged("MyReceipt"); } } 

public MainWindow()
{
    InitializeComponent();
    DataContext = this;
    MyReceipt = new Receipt { ReceiptPositions = new ObservableCollection<ReceiptPosition>() };

    MyReceipt.ReceiptPositions.Add(new ReceiptPosition { Article = "Foo" });
    MyReceipt.ReceiptPositions.Add(new ReceiptPosition { Article = "Bar" });
    MyReceipt.ReceiptPositions.Add(new ReceiptPosition { Article = "Baz" });

    MyReceipt.ReceiptPositions[0].Article = "Frabazamataz";
}

说明:

ItemsControl 允许您将列表绑定到其 ItemsSource 属性,以用作 DataTemplate 创建的每个视图的 DataContext。

可观察集合会在添加、删除或更改每个项目时自动发出 PropertyChange 通知。

这使您可以拥有一个仅基于您的数据的非常灵活的项目列表。


0
投票

Death的答案是正确的,即你使用了DataTemplates。如果您的视图和数据模板位于 MEF 插件中,那么您需要导入将视图模型映射到视图的插件和数据模板。在您发布的有关此问题的另一个问题中,很明显您正在尝试导出插件用户控件...我个人认为这有点误导。如果您的主应用程序使用 MVVM,那么您的插件也应该使用。在这种情况下,您的插件应该导出 IPlugin 类,并指定将其映射到视图的 DataTemplate。正如我在另一页上指出的,还必须导入数据模板,以便您可以将其添加到全局资源中。

我创建了一个项目,使用您在其他问题中提供的类来显示此操作,您可以在此处下载。主要看点是插件项目中的数据模板以及主项目中导入内容的两个地方。

enter image description here

请注意,在我的演示中,我要求每个插件为其视图和视图模型显式指定 DataTemplate,但您可能不想这样做,所以我还在 App 底部添加了一大块注释掉的代码.xaml.cs 显示了如何避免这种情况(为了使其正常工作,我必须将视图类型添加到 IPlugData 类,但这仅适用于本示例)。如果您选择手动创建 DataTemplates,则插件不需要指定数据模板,也不需要保存它们的自定义 ResourceDictionary。

如果您有任何疑问,请随时在评论中发帖。

© www.soinside.com 2019 - 2024. All rights reserved.