我有一个ListView,看起来像这样,它控制在我的应用程序中打开哪个选项卡。
<ListView Grid.ColumnSpan="2" Grid.Row="1" SelectedItem="{Binding Path=SelectedSubstanceName}" Name="listView" ItemsSource="{Binding Path=Substances}" HorizontalAlignment="Stretch" Margin="2" VerticalAlignment="Stretch">
<ListView.ContextMenu>
<ContextMenu>
<MenuItem Header="Lägg till" Command="{Binding AddSubstanceCommand}"/>
<MenuItem Header="Ta bort" Command="{Binding RemoveSubstanceCommand}"/>
</ContextMenu>
</ListView.ContextMenu>
<ListView.ItemTemplate>
<DataTemplate>
<WrapPanel>
<TextBlock Text="{Binding Name}" FontWeight="Bold" />
</WrapPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
我使用selectedsubstanename属性来检测打开哪个选项卡,或者切换到哪个选项卡,如果它已经打开了。
属性如下所示:
private SubstanceName selectedSubstanceName;
public SubstanceName SelectedSubstanceName
{
get
{
return selectedSubstanceName;
}
set
{
selectedSubstanceName = value;
OnPropertyChanged("SelectedSubstanceName");
if (selectedSubstanceName != null)
{
if (!Tabs.Any(t => t.Identify(selectedSubstanceName.SubstanceNameID, typeof(SubstanceTabsViewModel))))
AddTab(selectedSubstanceName);
else
SelectedTab = Tabs.First(t => t.Identify(selectedSubstanceName.SubstanceNameID, typeof(SubstanceTabsViewModel)));
}
}
}
我无法涵盖的情况是,当用户点击"someessubstance"时,相应的选项卡被打开,用户关闭它,"someessubstance"仍然被选中。如果用户想再次打开它,他必须选择一些其他物质(然后将被打开),然后再次点击"someessubstance"。是否有可能触发属性,甚至当点击相同的ListViewItem?
我知道我可以在双击时添加事件,但理想情况下,我希望避免事件和双击。
我认为问题是,在第一次点击一个项目后,列表的SelectedItem
得到设置。在第二次单击相同的项目后,SelectedItem
不会改变,因为它已经设置为该项目。您应该做的是在处理点击后将SelectedItem
设置为null
。
尝试在选项卡关闭后取消选择ListView中的所有项目。
YOURLISTVIEW.UnselectAll();
因此,下一次有人选择一个项目时,将会有一个变化。
您实际上不想使用ListView
类,而是简单地使用ItemsControl
,因为它是表示元素序列的最基本方式,但没有额外的SelectedItem
, SelectedValue
等,任何从Selector
派生的类都有。
ItemsControl
中的每个项目的问题。您想要的行为是知道特定项目何时被单击,这将使Button
类成为一个很好的候选者,因为它通过ICommand
接口处理单击行为。显然,既然您了解DataTemplate
s和样式,那么您应该已经知道可以自定义按钮的外观(视觉上),而不会牺牲实际行为(点击处理)。
<ItemsControl ItemsSource="{Binding Path=Substances}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Style="{StaticResource SomeStyleToChangeItsLook}"
Command="{Binding Path=SelectSubstanceCommand}"
CommandParameter="{Binding}"
Content="{Binding Path=Name}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
public ICommand SelectSubstanceCommand { get; private set; }
private void SelectSubstance(object parameter)
{
// Add the substance that was "clicked" on here however you want to do it.
}
请记住,我不知道你在使用什么框架,所以我只是给出了一个通用的例子,说明Command代码在视图模型中可能是什么样子的。MVVM和使用wpf出色UI的关键在于始终考虑您想要的行为以及哪些控件提供该行为。忽略它们的实际外观,因为这可以在不失去其行为的情况下进行更改。