WPF ListBoxItem MVVM 中的 SelectedItem 问题
SelectedItem issue in WPF ListBoxItem MVVM
我是 WPF 的新手,正在尝试按照 MVVM 设计模式进行设计。我的问题是,当用户在 ListBox 中选择此项时,我无法获取所选项目。感谢您的帮助,谢谢。我已经删除了一些不需要的方法中的代码。
抱歉,我应该添加名为:lbPositionAttributeMasters 的列表框不起作用。
XAML:
<Grid>
<StackPanel />
<ListBox x:Name="lbPositionAttributeMasters" ItemsSource="{Binding PositionAttributeMasterCollection}" SelectedItem="{Binding SelectedAttributeMaster, Mode=TwoWay}" Margin="0,10,280,10">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding PositionAttributeMasterDescription}"></TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox x:Name="lbPositionAttributesForMaster" ItemsSource="{Binding PositionAttributesCollection}" Margin="270,10,10,10">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding PositionAttributeDescription}"></TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
视图模型:
public event PropertyChangedEventHandler PropertyChanged;
private ObservableCollection<PositionAttributes> _positionAttributeMasterCollection;
private ObservableCollection<PositionAttributes> _positionAttributeCollection;
private IList<PositionAttributes> _positionAttributeMasterDescription;
private IList<PositionAttributes> _positionAttributeDescription;
private PositionAttributes _selectedAttributeMaster;
public PositionAttributesViewModel()
{
}
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public ObservableCollection<PositionAttributes> PositionAttributeMasterCollection
{
get { return _positionAttributeMasterCollection;}
set
{
_positionAttributeMasterCollection = value;
OnPropertyChanged("PositionAttributeMasterCollection");
}
}
public ObservableCollection<PositionAttributes> PositionAttributeCollection
{
get { return _positionAttributeCollection; }
set
{
_positionAttributeCollection = value;
OnPropertyChanged("PositionAttributeCollection");
}
}
public IList<PositionAttributes> PositionAttributeMasterDescription
{
get { return _positionAttributeMasterDescription; }
set
{
_positionAttributeMasterDescription = value;
OnPropertyChanged("PositionAttributeMasterDescription");
}
}
public PositionAttributes SelectedAttributeMaster
{
get{ return _selectedAttributeMaster; }
set
{
_selectedAttributeMaster = value;
OnPropertyChanged("SelectedAttributeMaster");
}
}
public IList<PositionAttributes> PositionAttributeDescription
{
get { return _positionAttributeDescription; }
set
{
_positionAttributeDescription = value;
OnPropertyChanged("PositionAttributeDescription");
}
}
/// <summary>
/// Gets all Attribute Masters and Sub Attribute Masters
/// </summary>
/// <returns></returns>
public ObservableCollection<PositionAttributes> GetPositionAttributeMasters()
{
foreach(var item in listofpositionAttributes)//Add to observable collection
{
PositionAttributeMasterCollection.Add(item);
}
return PositionAttributeMasterCollection;
}
foreach (var item in positionAttributesInMaster)//Add to observable collection
{
PositionAttributeCollection.Add(item);
}
}
return PositionAttributeCollection;
}
}
第一步。
在您的视图模型中添加中继命令
/// <summary>
/// Command which is fired when a list view item is selected in the main window
/// </summary>
public RelayCommand SelectionChangedCmd { get; private set; }
/// <summary>
/// The listview item selected from the collection.
/// </summary>
public Feature SelectedAttributedMaster { get; set; }
在您的视图模型的构造函数中:
public PositionAttributesViewModel()
{
PositionAttributeMasterCollection = new
ObservableCollection<PositionAttributes >();
SelectionChangedCmd = new RelayCommand(() =>
PositionAttributesSelectionChanged(), () => true);
}
//implement what you want to do on selection
private void PositionAttributesSelectionChanged()
{
if(PositionAttributeMasterCollection !=null &&
SelectedAttributedMaster !=null)
{
PositionAttributes feature = SelectedAttributedMaster as
PositionAttributes
//Update the window whenever we select a new feature.
Dispatcher.CurrentDispatcher.DynamicInvoke(delegate()
{
//further implementation
});
}
}
在您的 XAML 中添加引用和其余代码。
<Window x:Class="Something.MainWindow"
xmlns:i="clr-namespace:System.Windows.Interactivity; assembly=System.Windows.Interactivity"
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4">
<ListBox x:Name="lbPositionAttributeMasters" ItemsSource="{Binding PositionAttributeMasterCollection}" SelectedItem="{Binding SelectedAttributeMaster}" Margin="0,10,280,10">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding PositionAttributeMasterDescription}"></TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding SelectionChangedCmd}"
CommandParameter="{Binding}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ListBox>
您提供的代码按预期工作。你在评论中描述的是,在调试期间你看到 {ClientRatesWPF.Model.PositionAttributes}
作为一个值被设置为 SelectedAttributeMaster
.
这是完全正确的,因为调试器不知道如何向您显示更有意义的内容。你可以做两件事:
1) 将 DebuggerDisplay
属性应用到您的 class:
[DebuggerDisplay("Description = {PositionAttributeMasterDescription}")]
public class PositionAttributes
{
public string PositionAttributeMasterDescription { get; set; }
}
2) 使用 Visual Studio 调试器向您显示更多信息:
我是 WPF 的新手,正在尝试按照 MVVM 设计模式进行设计。我的问题是,当用户在 ListBox 中选择此项时,我无法获取所选项目。感谢您的帮助,谢谢。我已经删除了一些不需要的方法中的代码。
抱歉,我应该添加名为:lbPositionAttributeMasters 的列表框不起作用。
XAML:
<Grid>
<StackPanel />
<ListBox x:Name="lbPositionAttributeMasters" ItemsSource="{Binding PositionAttributeMasterCollection}" SelectedItem="{Binding SelectedAttributeMaster, Mode=TwoWay}" Margin="0,10,280,10">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding PositionAttributeMasterDescription}"></TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox x:Name="lbPositionAttributesForMaster" ItemsSource="{Binding PositionAttributesCollection}" Margin="270,10,10,10">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding PositionAttributeDescription}"></TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
视图模型:
public event PropertyChangedEventHandler PropertyChanged;
private ObservableCollection<PositionAttributes> _positionAttributeMasterCollection;
private ObservableCollection<PositionAttributes> _positionAttributeCollection;
private IList<PositionAttributes> _positionAttributeMasterDescription;
private IList<PositionAttributes> _positionAttributeDescription;
private PositionAttributes _selectedAttributeMaster;
public PositionAttributesViewModel()
{
}
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public ObservableCollection<PositionAttributes> PositionAttributeMasterCollection
{
get { return _positionAttributeMasterCollection;}
set
{
_positionAttributeMasterCollection = value;
OnPropertyChanged("PositionAttributeMasterCollection");
}
}
public ObservableCollection<PositionAttributes> PositionAttributeCollection
{
get { return _positionAttributeCollection; }
set
{
_positionAttributeCollection = value;
OnPropertyChanged("PositionAttributeCollection");
}
}
public IList<PositionAttributes> PositionAttributeMasterDescription
{
get { return _positionAttributeMasterDescription; }
set
{
_positionAttributeMasterDescription = value;
OnPropertyChanged("PositionAttributeMasterDescription");
}
}
public PositionAttributes SelectedAttributeMaster
{
get{ return _selectedAttributeMaster; }
set
{
_selectedAttributeMaster = value;
OnPropertyChanged("SelectedAttributeMaster");
}
}
public IList<PositionAttributes> PositionAttributeDescription
{
get { return _positionAttributeDescription; }
set
{
_positionAttributeDescription = value;
OnPropertyChanged("PositionAttributeDescription");
}
}
/// <summary>
/// Gets all Attribute Masters and Sub Attribute Masters
/// </summary>
/// <returns></returns>
public ObservableCollection<PositionAttributes> GetPositionAttributeMasters()
{
foreach(var item in listofpositionAttributes)//Add to observable collection
{
PositionAttributeMasterCollection.Add(item);
}
return PositionAttributeMasterCollection;
}
foreach (var item in positionAttributesInMaster)//Add to observable collection
{
PositionAttributeCollection.Add(item);
}
}
return PositionAttributeCollection;
}
}
第一步。 在您的视图模型中添加中继命令
/// <summary>
/// Command which is fired when a list view item is selected in the main window
/// </summary>
public RelayCommand SelectionChangedCmd { get; private set; }
/// <summary>
/// The listview item selected from the collection.
/// </summary>
public Feature SelectedAttributedMaster { get; set; }
在您的视图模型的构造函数中:
public PositionAttributesViewModel()
{
PositionAttributeMasterCollection = new
ObservableCollection<PositionAttributes >();
SelectionChangedCmd = new RelayCommand(() =>
PositionAttributesSelectionChanged(), () => true);
}
//implement what you want to do on selection
private void PositionAttributesSelectionChanged()
{
if(PositionAttributeMasterCollection !=null &&
SelectedAttributedMaster !=null)
{
PositionAttributes feature = SelectedAttributedMaster as
PositionAttributes
//Update the window whenever we select a new feature.
Dispatcher.CurrentDispatcher.DynamicInvoke(delegate()
{
//further implementation
});
}
}
在您的 XAML 中添加引用和其余代码。
<Window x:Class="Something.MainWindow"
xmlns:i="clr-namespace:System.Windows.Interactivity; assembly=System.Windows.Interactivity"
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4">
<ListBox x:Name="lbPositionAttributeMasters" ItemsSource="{Binding PositionAttributeMasterCollection}" SelectedItem="{Binding SelectedAttributeMaster}" Margin="0,10,280,10">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding PositionAttributeMasterDescription}"></TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding SelectionChangedCmd}"
CommandParameter="{Binding}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ListBox>
您提供的代码按预期工作。你在评论中描述的是,在调试期间你看到 {ClientRatesWPF.Model.PositionAttributes}
作为一个值被设置为 SelectedAttributeMaster
.
这是完全正确的,因为调试器不知道如何向您显示更有意义的内容。你可以做两件事:
1) 将 DebuggerDisplay
属性应用到您的 class:
[DebuggerDisplay("Description = {PositionAttributeMasterDescription}")]
public class PositionAttributes
{
public string PositionAttributeMasterDescription { get; set; }
}
2) 使用 Visual Studio 调试器向您显示更多信息: