How to bind data from View to UserControl with SoapBox

主宰稳场 提交于 2019-12-11 14:28:39

问题


I have my SoapBox.Document 'Register'

[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!";
    }
}

In this Document I want to user UserControls witch are kind of a own "View" Like a ListView for all ReceiptPositions

So now I got my Model Receipt and ReceiptPosition

Model Receipt

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

and 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; }
}

So now I want to add a UserControl witch displays a List of all articles in ReceiptPositions.

But how do I bind the data so that when a new ReceiptPosition gets added to the IList in Receipt the UserControl get 'refreshed' automatically?

Here is a visual example of whatI need..

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


回答1:


You can use an ItemsControl for this purpose.

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";
}

Explanation:

The ItemsControl allows you to bind a list to its ItemsSource Property to use as the DataContext to each view created by the DataTemplate.

The Observable Collection gives PropertyChange notifications automatically with each item added, removed, or changed.

This allows you to have a very flexible list of items based solely on your data.




回答2:


Death's answer is correct, i.e. you use DataTemplates. If your views and data templates are in a MEF plugin then you need to import both the plugins and the data templates that map the view models to the views. In the other question you posted about this it was obvious that you're trying to export your plugin user controls...personally I think this is a bit misguided. If your main application is using MVVM then your plugins should as well. In this case your plugins should export an IPlugin class and also specify a DataTemplate that maps it to a view. As I indicated on the other page, the data template must be imported as well so that you can add it to the global resources.

I've created a project that shows this in action using the classes you provided in your uother question, you can download it here. The main points to look at are the data templates in the plugin project and the two places where things are imported in the main project.

Note that in my demo I'm requiring each plugin to explicitly specify a DataTemplate for its view and view model, but you may not want to do this so I've also added a chunk of commented-out code at the bottom of App.xaml.cs that shows how to avoid that (to make it work I had to add the view type to the IPlugData class, but that's only needed for this one example). If you choose to create the DataTemplates manually then the plugins don't need to specify the data templates and they also don't need the custom ResourceDictionary that holds them.

If you have an questions feel free to post back here in the comments.



来源:https://stackoverflow.com/questions/33743792/how-to-bind-data-from-view-to-usercontrol-with-soapbox

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!