WPF 插件架构 itemscontrol 绑定不起作用
WPF plugin architecture itemscontrol binding not working
我们在 .Net 4.5(也测试过 4.6.2)上遇到了一个有趣的行为。
该项目有多个插件 dll。
main exe 将使用 MEF 从 DLL 加载数据模板(视图)和 ViewModel。
- 如果 StepView 和 StepVm 以及主框架代码在一个项目中(不使用 MEF),我在下面显示的 2 个按钮可以正常工作。
- 如果将 StepView 和 StepVm 移动到插件 dll,则只有第二个按钮可以使用。第一个显示输出控制台中的绑定错误。如果我可以post这里的错误消息,只是 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}");
});
}
因为 MEF 将您的 UserControl 动态加载到可视化树中,您可能会遇到 NameScope 问题,我认为这就是这里发生的问题。
老实说,您对 ElementName
绑定的使用存在问题,因为您处于 DateTemplate
中,这是一个封装边界,因此尽管它在 MEF 之外工作,但通常不受支持。
我们在 .Net 4.5(也测试过 4.6.2)上遇到了一个有趣的行为。 该项目有多个插件 dll。
main exe 将使用 MEF 从 DLL 加载数据模板(视图)和 ViewModel。
- 如果 StepView 和 StepVm 以及主框架代码在一个项目中(不使用 MEF),我在下面显示的 2 个按钮可以正常工作。
- 如果将 StepView 和 StepVm 移动到插件 dll,则只有第二个按钮可以使用。第一个显示输出控制台中的绑定错误。如果我可以post这里的错误消息,只是 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}");
});
}
因为 MEF 将您的 UserControl 动态加载到可视化树中,您可能会遇到 NameScope 问题,我认为这就是这里发生的问题。
老实说,您对 ElementName
绑定的使用存在问题,因为您处于 DateTemplate
中,这是一个封装边界,因此尽管它在 MEF 之外工作,但通常不受支持。