【发布时间】:2012-08-23 12:40:50
【问题描述】:
虽然这个问题与其他发布的问题非常相似,但它有一些转折!我在 ListBox 中有一个 ObservableCollection 项目,并使用 DataTemplate 来显示一些集合成员。但是,我定义了一个 ContextMenu,因此我可以使用 Command 参数执行在我的 ViewModel 中定义的 DelegateCommands。
我所有的 Bindings 都在这里工作,除了我需要使用 ListBox 中选择的项目的 CommandParameter 为 ViewModel 中的 Command 提供一个参数,以便命令知道要对哪个项目进行操作。但这是不可能的,因为我更改了 ContextMenu DataContext,因此我可以在 ViewModel 中访问 DelegateCommands。
我收到以下错误: System.Windows.Data 错误:4:找不到与引用“ElementName=instrumentListView”进行绑定的源。 BindingExpression:Path=SelectedItem;
ViewModel 中的命令按我的意愿调用,但它的参数始终为空。
我也尝试绑定到集合内的项目,但它们不可见,因为我必须切换我的 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;}
}
【问题讨论】:
标签: wpf binding contextmenu datatemplate observablecollection