虽然这个问题与其他人发布的非常相似,但它有一些变化!我在 ListBox 中有 ObservableCollection 项,并使用 DataTemplate 来显示某些集合成员。但是,我定义了 ContextMenu ,因此我可以使用命令参数执行在我的ViewModel中定义的 DelegateCommands 。
除了我需要使用ListBox中选择的项的CommandParameter为ViewModel中的Command提供一个参数,所以我的所有绑定都在这里工作,以便命令知道要对哪个项进行操作。但这是不可能的,因为我更改了ContextMenu DataContext,因此我可以访问ViewModel中的DelegateCommands。
我收到以下错误: System.Windows.Data错误:4:找不到与引用'ElementName = instrumentListView'绑定的源。 BindingExpression:路径=的SelectedItem;
ViewModel中的Command按我的意愿调用,但其参数始终为null。
我还尝试绑定到集合中的项目,但它们不可见,因为我必须切换我的DataContext。
以下是缩写的XAML文件:
<ListBox x:Name="instrumentListView" ItemsSource="{Binding Instruments}" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="instrumentStackPanel" HorizontalAlignment="Left" Orientation="Horizontal" Height="30" UseLayoutRounding="True" Tag="{Binding DataContext, RelativeSource={RelativeSource AncestorType=ListBox}}">
<Image Source="{Binding InstrumentIcon}" Margin="0,0,10,0"></Image>
<Label Content="{Binding Instrument}"></Label>
<StackPanel.ContextMenu >
<ContextMenu DataContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Add Instrument" Command="{Binding Path=AddInstrumentToTest}" CommandParameter="{Binding Instrument}"/>
<MenuItem Header="Remove Instrument" Command="{Binding Path=RemoveInstrumentFromTest}" CommandParameter="{Binding Instrument}"/>
</ContextMenu>
</StackPanel.ContextMenu>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
以下是我的ViewModel的副本:
public class ViewModel : INotifyPropertyChanged
{
public DelegateCommand<string> AddInstrumentToTest { get; set; }
public DelegateCommand<string> RemoveInstrumentFromTest { get; set; }
private ObservableCollection<IInstrument> instruments = new ObservableCollection<IInstrument>();
public ViewModel()
{
this.AddInstrumentToTest = new DelegateCommand<string >(this.OnaddInstrumentToTest, this.canAddInstrument);
this.RemoveInstrumentFromTest = new DelegateCommand<string >(this.OnremoveInstrumentFromTest, this.canRemoveInstrument);
}
public ObservableCollection<IInstrument> Instruments
{
...
}
public void OnaddInstrumentToTest(string inst) {...}
public void OnremoveInstrumentFromTest(string inst) {...}
public bool canRemoveInstrument(string inst) {...}
public bool canAddInstrument(string inst) {...}
...
}
这是IInstrument界面:
public interface IInstrument
{
string Model {get;set;}
string SerialNumber {get;set;}
InstrumentCommInterface.InstrumentInterface InstrumentComm {get;set;}
InstrumentClassification.InstrumentClass InstrumentClass {get;set;}
string FirmwareVersion {get;set;}
string Address {get;set;}
string Port {get;set;}
Lazy<IInstrumentFactory, IInstrumentPlugInMetaData> PlugInType {get;set;}
string Instrument {get;set;}
BitmapImage InstrumentIcon {get;set;}
bool SelectedForTest {get;set;}
ObservableCollection<string> Channels {get;set;}
}
答案 0 :(得分:0)
我会保留DataContext
并通过上下文菜单标记进行隧道传输。
<!-- Keep complete ListBox, allows acces of selected item and higher up DataContext -->
<StackPanel Tag="{Binding RelativeSource={RelativeSource AncestorType=ListBox}}">
<ContextMenu DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}"
Tag="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
所以现在DataContext
仍然是您的项目,如果您需要使用所选项目:
Tag.SelectedItem, RelativeSource={RelativeSource AncestorType=ContextMenu}