使用MVVM从插件加载UserControl(属性)

时间:2017-06-02 09:33:34

标签: c# wpf xaml mvvm user-controls

我是MVVM的完整菜鸟。到目前为止,我设法将我加载的插件(在集合中)的属性绑定到我的文本框以及一些组合框的可用插件。

现在,我正在努力在主机应用程序中显示他们的UI。

无处不在,我读过有关DataTemplate或MEF的内容,但我真的不知道该怎么做。在纸上看起来不错,但我不知道如何实现它。

我使用Reflection加载我的插件。

有可能吗?

我需要加载的所有东西都存储在Connections中:

Connection.cs

public class Connection
{
    public string ConnectionName { get; set; }
    public Plugin<IPlugin> ERP { get; set; }
    public Plugin<IPlugin> Shop { get; set; }

    public Connection(string connName)
    {
        ConnectionName = connName;
    }
}

Plugin.cs

public class Plugin<T>
{
    public Assembly PluginAssembly { get; set; }
    public Type[] TypeList { get; set; }

    public T PluginInstance { get; set; }

    public Type PluginType { get; set; }

    public Plugin()
    {

    }
}

IPlugin.cs

public interface IPlugin
{
    /// <summary>
    /// Contains information about the plugin, like version, author and type
    /// </summary>
    PluginInfo Info { get; }
    /// <summary>
    /// List of field lists for different mappings
    /// </summary>
    List<Fieldlist> Fieldlist { get; set; }

    UserControl UI { get; }

    Config Config { get; set; }

    /// <summary>
    /// Gets called at the start of the plugin
    /// </summary>
    void Load();
    /// <summary>
    /// Import function for transferring data into the plugin
    /// </summary>
    /// <param name="json">The data to be transferred</param>
    /// <param name="type">The type of data e.g articles, orders, etc.</param>
    void Import(string json, string type);
    /// <summary>
    /// Export function for transferring data out of the plugin
    /// </summary>
    /// <param name="type">The type of data e.g articles, orders, etc.</param>
    /// <returns>The JSON to be transferred</returns>
    string Export(string type);
}

&#34;受影响&#34;部分我的MainWindow.xaml:

<TabItem Header="ERP">
    <ContentControl Name="ccERP" Background="#FFE5E5E5" Content="{Binding ElementName=lbVerbindungen, Path=SelectedItem.ERP.PluginInstance.UI}"/>
</TabItem>
<TabItem Header="Shop">
    <ContentControl Name="ccShop" Background="#FFE5E5E5" Content="{Binding ElementName=lbVerbindungen, Path=SelectedItem.Shop.PluginInstance.UI}"/>
</TabItem>

编辑:我的应用程序在运行时使用程序集作为插件加载提到的插件,这些插件需要具有某种类型的UI。使用ccERP.Content = ((Connection)lbVerbindungen.SelectedItem).ERP.PluginInstance.UI;在代码中设置ContentControl的内容可以正常工作,但它并没有使用我上面使用的绑定。

EDIT2 :我的列表框是这样完成的:

<ListBox x:Name="lbVerbindungen" HorizontalAlignment="Left" Margin="10,10,0,43" Width="208" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Connections}" DisplayMemberPath="ConnectionName">
                    <ListBox.ItemContainerStyle>
                        <Style TargetType="ListBoxItem">
                            <EventSetter Event="Loaded" Handler="ListBoxItem_Loaded"/>
                            <Style.Triggers>
                                <Trigger Property="IsSelected" Value="True" >
                                    <Setter Property="FontWeight" Value="Bold" />
                                    <Setter Property="Background" Value="Transparent" />
                                    <Setter Property="Foreground" Value="Black" />
                                </Trigger>
                            </Style.Triggers>
                            <Style.Resources>
                                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black"/>
                                <!-- Background of selected item when focussed -->
                                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="LightCyan"/>
                                <!-- Background of selected item when not focussed -->
                                <SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="LightGray" />
                            </Style.Resources>
                        </Style>
                    </ListBox.ItemContainerStyle>
                </ListBox>

1 个答案:

答案 0 :(得分:0)

插件接口/类不应该有一个返回UserControl的属性。相反,您应该在视图中定义一个DataTemplate来定义插件的外观,例如:

<ContentControl Name="ccERP" Background="#FFE5E5E5" 
                        Content="{Binding ElementName=lbVerbindungen, Path=SelectedItem.ERP.PluginInstance}">
    <ContentControl.Resources>
        <DataTemplate DataType="{x:Type local:IPlugin}">
            <local:PluginUserControl />
        </DataTemplate>
    </ContentControl.Resources>
</ContentControl>

没有DataTemplate的隐式x:Key将自动应用于DataType属性指定类型的所有对象。

您可以在MSDN上阅读有关数据模板的更多信息:https://msdn.microsoft.com/en-us/library/ms742521(v=vs.110).aspx

修改

SelectedConnection属性添加到主窗口视图模型类:

private Connection _connection;
public Connection SelectedConnection
{
    get
    {
        return _connection;
    }
    set
    {
        _connection = value;
        OnProprtyChanged();
    }
}

...并将SelectedItem的{​​{1}}属性绑定到此属性:

ListBox

然后你应该能够将<ListBox x:Name="lbVerbindungen" .... ItemsSource="{Binding Connections}" SelectedItem="{Binding SelectedConnection}" DisplayMemberPath="ConnectionName"> ... 的{​​{1}}属性绑定到UI属性,如下所示:

Content