在我的WinRT应用程序中,我想显示状态值列表并突出显示当前状态。当列表显示时,它应该是只读的,因此不与用户交互。虽然我使用ListView,但我希望禁用任何选择功能。我认为禁用ListView可以解决这个问题。 但是现在在我的代码背后,我有;
public IList<JobStatusItem> StatusList
{
get
{
var values = Enum.GetValues(typeof(JobStatus));
var selected = Status.ToString();
var i = 0;
var list = new List<JobStatusItem>();
foreach (var value in values)
{
i++;
var item = GetStatusDisplay(value.ToString());
list.Add(new JobStatusItem
{
Id = i,
Status = item,
Selected = value.ToString().Equals(selected)
});
}
return list;
}
}
对于我的XAML,我有
<ListView x:Name="ListStatus"
IsItemClickEnabled="False"
IsSwipeEnabled="False"
SelectionMode="Single"
ItemsSource="{Binding Path=AssignedJobs.SelectedDay.SelectedJob.StatusList, Mode=OneWay}"
>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="IsSelected" Value="{Binding Path=Selected, Mode=OneWay}"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Status}"></TextBlock>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
当我运行此选项时,所选状态的样式不会被选中。为什么会这样,我该如何解决这个问题?
答案 0 :(得分:2)
代码中的绑定表达式(<Setter Property="IsSelected" Value="{Binding Path=Selected, Mode=OneWay}"/>
)不会起作用,因为上下文不在项目级别。
由于WinRT中缺少祖先绑定,因此很难使用纯绑定来实现您想要的效果;但是,在后面的代码中检查 IsSelected
属性非常简单。在一天结束时,如果您想要一个纯XAML解决方案,您始终可以将下面的代码包装在Behavior
内。
您基本上想要订阅ListView
的{{3}}事件,并手动设置IsSelected
的{{1}}属性以匹配ItemContainer
属性你的模型Selected
。像这样的东西 -
JobStatusItem
由于您需要包含突出显示选项的只读列表,因此最好通过将 private void OnListViewContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)
{
if (args.ItemContainer != null && !args.InRecycleQueue && args.Phase == 0)
{
args.ItemContainer.IsSelected = ((JobStatusItem)args.Item).Selected;
设置为ListView
来完全禁用SelectionMode
上的任何点击/点按互动}。
然后在None
内,用DataTemplate
包裹TextBlock
,并在Border
属性时为Border
提供不同的Background
是Selected
。
答案 1 :(得分:1)
因此,我希望您希望禁用手动选择,同时维护程序化选择。列表视图中的项目。
实现您要执行的操作的最简单方法是将ListView定义为SelectionMode="Single"
,并将SelectedItem属性绑定到ViewModel的相应属性。要阻止任何手动交互,只需在IsHittestVisible="True"
上放置一个网格即可阻止任何手动交互。如下所示:
<Grid>
<ListView x:Name="ListStatus"
SelectionMode="Single"
ItemsSource="{Binding StatusList}"
SelectedItem="{Binding SelectedItem}"
ItemTemplate="{StaticResource UnselectedListDataTemplate}"/>
<Grid IsHitTestVisible="True" Background="Transparent" />
</Grid>
我会选择完全不同的方法。
您尝试实现的更方便的方法是设置ListView.SelectionMode="None"
并使用ItemTemplateSelector
或ItemContainerStyleSelector
来切换突出显示版本和普通版本之间的模板/样式。
public class JobStatusItemTemplateSelector : DataTemplateSelector
{
public DataTemplate SelectedTemplate { get; set; }
public DataTemplate UnselectedTemplate { get; set; }
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
var element = item as JobStatusItem;
if (element == null) return UnselectedTemplate;
return element.Selected ? SelectedTemplate : UnselectedTemplate;
}
}
将ListView定义为:
<Page.Resources>
<DataTemplate
x:DataType="local:JobStatusItem"
x:Key="SelectedListDataTemplate">
<TextBlock Text="{Binding Status}" FontWeight="ExtraBold" Foreground="DarkOrchid"/>
</DataTemplate>
<DataTemplate
x:DataType="local:JobStatusItem"
x:Key="UnselectedListDataTemplate">
<TextBlock Text="{Binding Status}" />
</DataTemplate>
<local:JobStatusItemTemplateSelector x:Key="ListTemplateSelector"
SelectedTemplate="{StaticResource SelectedListDataTemplate}"
UnselectedTemplate="{StaticResource UnselectedListDataTemplate}"/>
</Page.Resources>
<ListView x:Name="ListStatus"
SelectionMode="None"
ItemsSource="{Binding StatusList}"
ItemTemplateSelector="{StaticResource ListTemplateSelector}">
</ListView>
这样,您就可以轻松区分已发生,正在进行且将来会发生的状态步骤,甚至可以让您轻松整合过去时发生的错误等步骤。
根据您使用的是TemplateSelector
或StyleSelector
,您甚至可以通过不同的模板实现符号,图片等。