【问题标题】:React on user clicking already selected ListViewItem, MVVM对用户单击已选择的 ListViewItem、MVVM 做出反应
【发布时间】:2014-08-22 19:22:05
【问题描述】:

我有一个看起来像这样的 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>

我使用 SelectedSubstanceName 属性来检测要打开或切换到哪个选项卡(如果它已经打开)。

该属性如下所示:

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)));
        }
    }
}

我无法涵盖的情况是当用户单击“someSubstance”时,打开相应的选项卡,用户将其关闭,并且仍然选择“someSubstance”。如果用户想再次打开它,他必须选择一些其他物质(然后将被打开),然后再次单击“someSubstance”。点击同一个ListViewItem是否也能触发属性?

我知道我可以在双击时添加事件,但理想情况下,我想避免事件和双击。

【问题讨论】:

    标签: c# wpf mvvm


    【解决方案1】:

    我认为问题在于,在第一次单击一个项目后,列表的 SelectedItem 被设置。第二次单击同一项目后,SelectedItem 不会更改,因为它已经设置为该项目。您应该在处理点击后将SelectedItem 设置为null

    【讨论】:

      【解决方案2】:

      关闭选项卡后,尝试取消选择 ListView 中的所有项目。

      YOURLISTVIEW.UnselectAll();
      

      所以下次有人选择一个项目时就会发生变化。

      【讨论】:

        【解决方案3】:

        您实际上并不想使用ListView 类,而是简单地使用ItemsControl,因为它是表示元素序列的最基本方式,但没有诸如SelectedItem 之类的额外内容, SelectedValue 等任何派生自 Selector 的类都有。

        从那里开始,这只是如何 表示ItemsControl 中的每个项目的问题。您想要知道特定项目何时被单击,这将使Button 类成为一个很好的候选者,因为它通过ICommand 接口处理单击行为。显然,既然您对DataTemplates 和一般样式有所了解,您应该已经知道您可以自定义按钮的外观(视觉)而不牺牲实际行为(点击处理)。


        <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.
        }
        

        请记住,我不知道您使用的是什么框架,所以我只是给出了一个通用示例,说明命令代码在您的视图模型中的外观。 MVVM 和使用 WPF 令人敬畏的 UI 的关键是始终考虑您想要什么行为以及哪些控件提供该行为。忽略它们的实际外观,因为可以在不丢失该行为的情况下进行更改。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-08-19
          • 2016-10-02
          • 1970-01-01
          • 2020-04-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多