C# WinRT XAML-如何在列表视图中设置选定项的样式?
在我的WinRT应用程序中,我想显示状态值列表并突出显示当前状态。当列表显示时,它应该是只读的,因此不会与用户交互。虽然我使用的是ListView,但我希望禁用任何选择功能。我认为禁用ListView就可以做到这一点。 但现在在我的代码背后,我有C# WinRT XAML-如何在列表视图中设置选定项的样式?,c#,xaml,windows-runtime,C#,Xaml,Windows Runtime,在我的WinRT应用程序中,我想显示状态值列表并突出显示当前状态。当列表显示时,它应该是只读的,因此不会与用户交互。虽然我使用的是ListView,但我希望禁用任何选择功能。我认为禁用ListView就可以做到这一点。 但现在在我的代码背后,我有 public IList<JobStatusItem> StatusList { get { var values = Enum.GetValues(typeof(JobS
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;
}
}
公共IList状态列表
{
得到
{
var values=Enum.GetValues(typeof(JobStatus));
var selected=Status.ToString();
var i=0;
var list=新列表();
foreach(值中的var值)
{
i++;
var item=GetStatusDisplay(value.ToString());
列表。添加(新JobStatusItem)
{
Id=i,
状态=项目,
Selected=value.ToString().Equals(已选)
});
}
退货清单;
}
}
对于我的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>
当我运行此命令时,所选状态的样式不是selected。这是为什么?我如何解决这一问题?代码中的绑定表达式(
)无法工作,因为上下文不在项目级别
由于WinRT中缺少祖先绑定,很难使用纯绑定来实现您想要的;但是,在代码隐藏中检查IsSelected
属性非常简单。最后,如果您想要一个纯XAML解决方案,您可以将下面的代码包装到行为中
基本上,您希望订阅您的列表视图的事件
,并手动设置ItemContainer
的IsSelected
属性,以匹配您的模型JobStatusItem
的Selected
属性。像这样的-
private void OnListViewContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)
{
if (args.ItemContainer != null && !args.InRecycleQueue && args.Phase == 0)
{
args.ItemContainer.IsSelected = ((JobStatusItem)args.Item).Selected;
另一种可能的解决办法
由于您需要一个带有突出显示选择的只读列表,因此最好通过将其SelectionMode
设置为None
来完全禁用ListView
上的任何单击/点击交互
然后在数据模板
中,用边框
包裹文本块
,并在所选属性为true
时,为边框
提供不同的背景
,我想您希望在维护编程选择的同时,禁用ListView中项目的手动选择
要实现您尝试的操作,最简单的方法是将ListView定义为SelectionMode=“Single”
,并将SelectedItem属性绑定到ViewModel的相应属性。要阻止任何手动交互,只需使用ishitsetvisible=“True”
在其上放置一个网格即可阻止任何手动交互。例如:
然而,我会选择一种完全不同的方法
要实现此目标,更方便的方法是设置ListView.SelectionMode=“None”
,并使用ItemTemplateSelector
或ItemContainerStyleSelector
在突出显示的版本和正常版本之间切换模板/样式
公共类JobStatusItemTemplateSelector:DataTemplateSelector
{
公共数据模板SelectedTemplate{get;set;}
公共数据模板未选择模板{get;set;}
受保护的覆盖数据模板SelectTemplateCore(对象项,DependencyObject容器)
{
var元素=作为JobStatusItem的项目;
if(element==null)返回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>