WPF插件架构项目控件绑定无效

时间:2019-01-10 00:35:37

标签: c# wpf mvvm mef

我们在.Net 4.5(还测试了4.6.2)上遇到了一个有趣的行为。 该项目有多个插件dll。

主要exe将使用MEF从DLL加载DataTemplates(视图)和ViewModels。

  1. 如果StepView和StepVm与主机代码在一个项目中(不使用MEF),则下面显示的2个按钮都可以使用。
  2. 如果将StepView和StepVm移至插件dll,则仅第二个按钮有效。第一个显示输出控制台中的绑定错误。如果我可以在此处发布错误消息,则需要与经理联系,只是wpf标准绑定错误。

有人可以在这里分享一些见解吗? 谢谢。

StepView

<UserControl
x:Class="StepView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:ScriptHighlighter"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DataContext="{d:DesignInstance local:StepVm}"
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
<Grid>
    <ItemsControl x:Name="XItemsControl" ItemsSource="{Binding Names}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <Button
                        Content="Not Wokring in plugin mode"
                        Command="{Binding ElementName=XItemsControl, Path=DataContext.DeleteCommand}"
                        CommandParameter="{Binding}" />
                    <Button
                        Content="Wokrs in plugin mode"
                        Command="{Binding Path=DataContext.DeleteCommand, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}, Mode=FindAncestor}}"
                        CommandParameter="{Binding}" />
                </StackPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

StepVm

public class StepVm:ViewModelBase
{
    public StepVm()
    {
        this.Names = new List<string>(){"1", "2", "3"};
    }
    public List<string> Names { get; set; }
    public ICommand DeleteCommand => new RelayCommand<string>(n =>
    {
        Debug.WriteLine($"logic to delete  {n}");
    });
}

1 个答案:

答案 0 :(得分:1)

由于MEF将您的UserControl动态加载到可视树中,因此您可能会遇到NameScope的问题,我认为这是在发生这种情况。

WPF XAML Namescopes

说实话,您使用ElementName绑定是有问题的,因为您位于DateTemplate(这是一个封装边界)中,因此尽管它在MEF之外运行,但通常不受支持。 >