【问题标题】:How does this setter end up working? (ListView MultiSelect)这个二传手最终是如何工作的? (列表视图多选)
【发布时间】:2013-09-30 18:07:44
【问题描述】:

我有一个 ViewModel,我将它用作 ItemsSourceListView,它实现了一个名为 ISelectable 的接口:

/// <summary>
/// An interface that should be implemented by a ViewModel that can be 
/// marked as selected, when multiple selections are allowed.
/// </summary>
public interface ISelectable
{
    /// <summary>
    /// Gets or sets a value indicating whether this instance is selected.
    /// </summary>
    /// <value>
    /// <c>true</c> if this instance is selected; otherwise, <c>false</c>.
    /// </value>
    bool IsSelected { get; set; }
}

ListView 显示“搜索客户端”功能的搜索结果,因此所有项目都是 ClientViewModel 实例 - 并且 ClientViewModel 实现 ISelectable 因此具有 IsSelected 属性:

<ListView x:Name="SearchResultsList" ItemsSource="{Binding SearchResults}">
    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="IsSelected" Value="{Binding IsSelected}" />
        </Style>
    </ListView.ItemContainerStyle>
    <ListView.ItemTemplate>
        <DataTemplate DataType="{x:Type viewModels:ClientViewModel}">
            <Label Content="{Binding Name}" />
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

这很好用;在窗口的 ViewModel 中,我可以定义如下属性:

public IEnumerable<ClientViewModel> SelectedClients 
{ 
    get 
    { 
        return _searchResults == null 
                              ? null 
                              : _searchResults.Where(e => e.IsSelected); 
    } 
}

我得到了我所期望的。

我的问题是关于 XAML 的以下部分 - 设计者在 Value="{Binding}" 部分中强调 IsSelected 并说“无法在类型 [窗口的 ViewModel 类型] 的数据上下文中解析属性 'IsSelected'” :

    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="IsSelected" Value="{Binding IsSelected}" />
        </Style>
    </ListView.ItemContainerStyle>
  • 如何告诉设计者ListView.ItemContainerStyle的数据上下文应该和数据模板的一致?
  • 如果 XAML 设计人员说它无法解决,它最终如何在运行时工作?

更新

这是一个 ReSharper 警告。我可以关闭它,但我想知道的是 setter 最终是如何工作的,因为我得到了正确的自动完成功能:

    <ListView.ItemTemplate>
        <DataTemplate DataType="{x:Type viewModels:ClientViewModel}">
            <Label Content="{Binding Name}" /> <!-- "Name" is available from IntelliSense -->
        </DataTemplate>
    </ListView.ItemTemplate>

但不是为了那个:

    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="IsSelected" Value="{Binding IsSelected}" /> 
            <!-- "IsSelected" isn't, IntelliSense is showing the members of the Window's ViewModel -->
        </Style>
    </ListView.ItemContainerStyle>

【问题讨论】:

  • XAML 设计器不是那么聪明,我猜。您可以尝试在StyleSetter 中设置d:DataContext 属性。不过,我不确定它是否会起作用。
  • 构建项目后是否仍然显示错误?
  • @nit 是的。我应该说它以蓝色突出显示,...并且我正在运行 ReSharper 7.1,不确定如何使用 R# 关闭 XAML 解析以确保它不是 R# 在这里误导...
  • 它将是 Resharper,因为我从未见过默认设计器 intellisense 在 Binding experssion 中指出此类错误
  • 对。看起来像一个 R# 故障,我可以编辑“静态上下文中未解析的符号”的检查选项,如果我把它变成“提示”,下划线就会变成一个 R# 提示。绝对是 ReSharper。看到我指定上下文的选项不要低于 ListView 我想我唯一的选择是忽略这个警告......这很烦人,因为 R# 通常非常准确。

标签: c# wpf xaml resharper


【解决方案1】:

这应该是 Resharper 做的伎俩,因为我从未见过默认设计器 intellisense 在 Binding experssion 中指出这种类型的错误。您可以完全切换 Resharper 以完全证明它。

由于您在 ListViewItem 样式中设置属性并且您正在使用 {Binding IsSelected},因此它将在每个 listviewitem 的 DataContext 中搜索 IsSelected,这是您的 ClientViewModel 并且具有 IsSelected 属性...因此绑定是完美的.. 设计师不够聪明,无法深入探究

【讨论】:

  • 这是 R# 的事情.. 但我仍然想了解这里发生了什么以使绑定起作用,因为本地 VS 设计器正在为窗口的 ViewModel 的成员提供自动完成功能,不是ItemsSource 类型的成员 - 换句话说,是的,这是一个 R# 警告,但据我所知,它是准确的。
  • 因为您在 ListViewItem 样式中设置属性并且您正在使用 {Binding IsSelected},它将在每个 listviewitem 的 DataContext 中搜索 IsSelected,这是您的 ClientViewModel 并且具有 IsSelected 属性...因此绑定是完美..设计师不够聪明,无法深入探索
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-15
  • 1970-01-01
  • 2020-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多