【问题标题】:ListBox "IsSelected" binding not working列表框“IsSelected”绑定不起作用
【发布时间】:2015-02-09 11:29:22
【问题描述】:

我一直在寻找这个问题的答案,但没有运气,据我所知,我有所有正确的元素,但由于某种原因,这不想工作。

我需要 IsSelected setter 在 ListBox 中选择项目时运行。

XAML 代码

<ListBox HorizontalAlignment="Left" Height="226" Margin="10,34,0,0" VerticalAlignment="Top" Width="132" ItemsSource="{Binding Activities}" >
        <ListBox.ItemContainerStyle>
            <Style TargetType="{x:Type ListBoxItem}">
                <Setter Property="IsSelected" Value="{Binding IsSelected}" />
            </Style>
        </ListBox.ItemContainerStyle>
     </ListBox>

C# 视图模型

 private bool m_isSelected;
 public bool IsSelected
    {
        get { return m_isSelected; }
        set
        {
            if (value != m_isSelected)
            {
                m_isSelected = value;

                if (m_isSelected)
                {
                    CurrentViews = getCurrentViews((BasePropertyTypeVM)CurrentActivity);
                    AvailableViews = getAvailableViews(Properties);
                }

                OnPropertyChanged(() => IsSelected);
            }
        }
    }

非常感谢,

山姆

【问题讨论】:

  • 你已经在setter中设置了一个断点并检查它没有被命中?
  • 是的,我在设置器上使用了断点,它从未被调用过。
  • 仔细检查一下,您的 IsSelected 属性在 Activity ViewModel 上对吗?而不是在父虚拟机上。
  • 如果 getCurrentViews 或 getAvailableViews 遇到异常,setter 将无法工作
  • @Clemens DataContext.IsSelectedRelativeSource Self 会起作用吗???

标签: c# wpf listbox


【解决方案1】:

ListBoxItem 的IsSelected 属性绑定到IsSelected 视图模型属性,该属性必须是数据项类型的属性,即Activities 集合的元素类型。

你需要声明这样一个数据项类,例如

public class Activity : INotifyPropertyChanged
{
    public string Name { get; set; }

    private bool isSelected;
    public bool IsSelected
    {
        get { return isSelected; }
        set
        {
            if (value != isSelected)
            {
                value = isSelected;
                ...
            }
        }
    }

并像这样声明Activities 集合:

public ObservableCollection<Activity> { get; set; }

Activity 类的Name 属性可用于ListBoxItem 的DataTemplate:

<ListBox ... ItemsSource="{Binding Activites}">
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="IsSelected" Value="{Binding IsSelected}"/>
        </Style>
    </ListBox.ItemContainerStyle>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Name}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

【讨论】:

    【解决方案2】:

    试试这个:

     <Setter Property="IsSelected" Value="{Binding DataContext.IsSelected, 
    RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBox}}}" />
    

    【讨论】:

    • 现在触发了 setter,但是它选择了 ListBox 中的所有内容,有什么想法吗?
    • @SamEmber 您的 IsSelected 属性不应位于包含您的活动 ObservableCollection 的 ViewModel 中。相反,IsSelected 应该在“Activity”ViewModel 中,或者您应该在父 ViewModel 中有 SelectedItem 属性并在 ListBox xaml 中绑定到它。
    • 看看 Clemens 的回答,它为您简化了一切。
    • @SamEmber 想想看。您需要为每个项目提供一个 IsSelected 属性,即为活动集合中的每个元素提供一个。此处介绍的解决方案并不能满足您的要求,因为它将所有 ListBoxItem 的 IsSelected 属性绑定到同一属性,该属性只能有一个值。因此,所有项目要么被选中,要么不被选中。
    • @Clemens 是的,这很完美,感谢您的帮助 Clemens
    猜你喜欢
    • 2013-06-22
    • 1970-01-01
    • 2012-09-10
    • 2014-01-13
    • 2018-06-16
    • 1970-01-01
    • 2011-01-10
    • 2023-04-04
    • 2014-04-04
    相关资源
    最近更新 更多