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

时间:2015-11-16 20:12:51

标签: c# wpf user-controls mef

我有我的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是一种自己的" View" 就像所有ReceiptPositions的ListView一样

所以现在我得到了Model Receipt和ReceiptPosition

模特收据

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

和Model ReceiptPosition

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会刷新&#39;自动?

以下是我需要的一个视觉示例..

Host with Data and two PLugins wich each show the same Data but in a different way.

2 个答案:

答案 0 :(得分: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。

Observable Collection会自动为每个项目添加,删除或更改PropertyChange通知。

这使您可以根据您的数据拥有非常灵活的项目列表。

答案 1 :(得分:0)

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

我创建了一个项目,使用您在其他问题中提供的课程来显示此操作,您可以download it here。要看的主要内容是插件项目中的数据模板以及在主项目中导入内容的两个位置。

enter image description here

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

如果您有任何问题,请随时在评论中回复。