[英]WinRT XAML - how do I style a selected item in a list view?
在我的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>
當我運行此選項時,所選狀態的樣式不會被選中。 為什么這樣,我該如何解決這個問題?
您的代碼中的綁定表達式( <Setter Property="IsSelected" Value="{Binding Path=Selected, Mode=OneWay}"/>
)將不起作用,因為上下文不在項目級別。
由於WinRT中缺少祖先綁定,因此很難使用純綁定來實現您想要的效果; 但是,在后面的代碼中檢查 IsSelected
屬性非常簡單。 在一天結束時,如果您需要純XAML解決方案,您始終可以將下面的代碼包裝在Behavior
。
你基本上要訂閱ContainerContentChanging
你的事件ListView
和手動設置IsSelected
的財產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;
由於您需要具有突出顯示選項的只讀列表,因此通過將其SelectionMode
設置為None
來完全禁用ListView
上的任何單擊/點擊交互可能是個好主意。
然后在DataTemplate
,使用Border
包裝TextBlock
,並在Selected
屬性為true
時為Border
提供不同的Background
。
所以,我想你想要在保持程序選擇的同時禁用 ListView中的項目手動 選擇 。
實現您要執行的操作的最簡單方法是將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
您甚至可以通過不同的模板實現符號,圖像等。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.