如何动态更改列表中基于按钮值的图标?
How to dynamically change the icon on a button based value in a list?
我有以下 xaml 代码:
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.ContextActions>
<MenuItem Text="Check In"
Clicked="CheckInFile"/>
<MenuItem Text="Check Out"
Clicked="CheckOutFile"/>
<MenuItem Text="Download"
Clicked="DownloadFile"/>
<MenuItem Text="Upload Local Copy"
Clicked="UploadFile"/>
</ViewCell.ContextActions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<Label Grid.Column="0" Text="{Binding Path=DriveItem.Name}"
FontSize="Small" />
<Label Grid.Column="1""
FontFamily="Segoe MDL2 Assets"
Text="{Binding PublicationStatus}"
/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
和相关的cs代码:
protected override async void OnAppearing()
{
var directoryContents = await App.GraphClient.Sites[siteID].Lists[sharedDocsDriveId]
.Items
.Request()
//.Expand(item => item.DriveItem)
.Expand("driveItem($select=publication,name,id,description,file,webUrl)")
.GetAsync();
SharedDocumentList.ItemsSource = directoryContents.CurrentPage.ToList();
}
对于返回的每个项目,它包含有关文件的信息 - 如果它当前已签出或未签出。该字段是“级别”,如下所示/
directoryContents.CurrentPage[i].DriveItem.Publication
{Microsoft.Graph.PublicationFacet}
AdditionalData: null
Level: "checkout"
ODataType: null
VersionId: "4.0"
如果 Level 的值为“checkout”,我想使用以下方法显示锁定的图标:
https://docs.microsoft.com/en-us/windows/apps/design/style/segoe-ui-symbol-font
但如果它是“已发布”,我想使用解锁图标。
有没有一种简单的方法可以在 XAML 中执行某种 IF 语句来计算 DriveItem.Publication.Level 的值,然后显示适当的图标?我开始尝试在名为 publicationStatus 的代码隐藏中公开一个新的 属性,但是......也许这有点过分了。我觉得有一个我没有想到的更简单的方法?
编辑 1
所以我更新了 xaml 以使用 datatrigger 方法,但我得到的错误是在类型 BindingExtension 中找不到 属性“RelativeSource”。
<ListView x:Name="SharedDocumentList"
HasUnevenRows="true"
>
<ListView.Resources>
<Style x:Key="PublicationStatus" TargetType="Label">
<Setter Property="FontFamily" Value="Segoe MDL2 Assets" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Tag, RelativeSource={RelativeSource Self}}"
Value="checkout">
<Setter Property="Text" Value="\uE701"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=Tag, RelativeSource={RelativeSource Self}}"
Value="published">
<Setter Property="Text" Value="\uE702"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ListView.Resources>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.ContextActions>
<MenuItem Text="Check In"
Clicked="CheckInFile"/>
<MenuItem Text="Check Out"
Clicked="CheckOutFile"/>
<MenuItem Text="Download"
Clicked="DownloadFile"/>
<MenuItem Text="Upload Local Copy"
Clicked="UploadFile"/>
</ViewCell.ContextActions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<Label Grid.Column="0" Text="{Binding Path=DriveItem.Name}"
FontSize="Small" />
<Label Grid.Column="1"
Style="{StaticResource PublicationStatus}"
Tag="{Binding PublicationStatus}" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
编辑 2
这是我尝试使用 ValueConverter。
下面是 class 的部分代码:
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class SPDocumentLibraryContentsPage : ContentPage
{
public string IconValue { get; set; }
public SPDocumentLibraryContentsPage()
{
InitializeComponent();
IconValue = "checkout";
//this.DataContext doesn't exist.
}
Xaml 页面上的 ListView 如下所示:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<Label Grid.Column="0" Text="{Binding Path=DriveItem.Name}"
FontSize="Small" />
<Label x:Name="testBlock" Grid.Column="2"
Text="{Binding IconValue,Converter={StaticResource IconValueConverter}}" FontFamily="Segoe MDL2 Assets" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
而且我能够创建 IconConverter class 没问题。
这里只是一个片段:
namespace GraphTutorial.Models
{
public class IconValueConverter : Xamarin.Forms.IValueConverter
{
}
编辑 3
为了得到工作的答案,我做了以下事情:
<Label Grid.Column="0" Text="{Binding Path=DriveItem.Name}" FontSize="Small" />
<Label Grid.Column="1" Text="{Binding Path=DriveItem.Publication.Level,Converter={StaticResource IconValueConverter}}" FontFamily="Segoe MDL2 Assets" />
有一种聪明的方法可以通过 Trigger
和 Tag
属性 来避免使用 IValueConverter
或从在 Style
.
中
在列表视图或根元素中
<ListView.Resources>
<Style x:Key="PublicationStatus" TargetType="Label">
<Setter Property="FontFamily" Value="Segoe MDL2 Assets" />
<Style.Triggers>
<Trigger Property="Tag"
Value="checkout">
<Setter Property="Text" Value="\uE701"/>
</Trigger>
<Trigger Property="Tag"
Value="published">
<Setter Property="Text" Value="\uE702"/>
</Trigger>
</Style.Triggers>
</Style>
</ListView.Resources>
然后在代码中:
<Label Grid.Column="1"
Style="{StaticResource PublicationStatus}"
Tag="{Binding PublicationStatus}" />
您也可以重复使用一种样式并将其放入某些 ResourceDictionary
.
警告。未测试。
您的应用似乎是 Xamarin UWP 应用,而不是本机 UWP 应用。
您也可以尝试在使用绑定时使用 ValueConverter。您需要做的是创建一个 ValueConverter class 并在 ValueConverter 中制定您自己的将不同字符串转换为不同图标的逻辑。
之后,您只需要在绑定中使用 ValueConverter 作为参数即可。
这是我在本机 UWP 应用程序中测试过的示例代码。它应该在 Xamarin UWP 应用程序中工作。您需要将 Textblock
替换为 Label
。
代码隐藏:
public class IconValueConverter: IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
string OutputValue ;
string textvalue = value as string;
if (textvalue.Equals("checkout"))
{
OutputValue = "\uE701";
}
else if (textvalue.Equals("published"))
{
OutputValue = "\uE702";
}
else
{
OutputValue = "\uE703";
}
return OutputValue;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
主页:
public string IconValue { get; set;}
public MainPage()
{
this.InitializeComponent();
IconValue = "checkout";
this.BindingContext = this;
}
Xaml代码:
<Page.Resources>
<local:IconValueConverter x:Key="IconValueConverter"/>
</Page.Resources>
<Grid>
<TextBlock x:Name="MyTextBlcok" Text="{Binding IconValue,Converter={StaticResource IconValueConverter}}" FontFamily="Segoe MDL2 Assets" />
</Grid>
我有以下 xaml 代码:
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.ContextActions>
<MenuItem Text="Check In"
Clicked="CheckInFile"/>
<MenuItem Text="Check Out"
Clicked="CheckOutFile"/>
<MenuItem Text="Download"
Clicked="DownloadFile"/>
<MenuItem Text="Upload Local Copy"
Clicked="UploadFile"/>
</ViewCell.ContextActions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<Label Grid.Column="0" Text="{Binding Path=DriveItem.Name}"
FontSize="Small" />
<Label Grid.Column="1""
FontFamily="Segoe MDL2 Assets"
Text="{Binding PublicationStatus}"
/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
和相关的cs代码:
protected override async void OnAppearing()
{
var directoryContents = await App.GraphClient.Sites[siteID].Lists[sharedDocsDriveId]
.Items
.Request()
//.Expand(item => item.DriveItem)
.Expand("driveItem($select=publication,name,id,description,file,webUrl)")
.GetAsync();
SharedDocumentList.ItemsSource = directoryContents.CurrentPage.ToList();
}
对于返回的每个项目,它包含有关文件的信息 - 如果它当前已签出或未签出。该字段是“级别”,如下所示/
directoryContents.CurrentPage[i].DriveItem.Publication
{Microsoft.Graph.PublicationFacet}
AdditionalData: null
Level: "checkout"
ODataType: null
VersionId: "4.0"
如果 Level 的值为“checkout”,我想使用以下方法显示锁定的图标: https://docs.microsoft.com/en-us/windows/apps/design/style/segoe-ui-symbol-font 但如果它是“已发布”,我想使用解锁图标。
有没有一种简单的方法可以在 XAML 中执行某种 IF 语句来计算 DriveItem.Publication.Level 的值,然后显示适当的图标?我开始尝试在名为 publicationStatus 的代码隐藏中公开一个新的 属性,但是......也许这有点过分了。我觉得有一个我没有想到的更简单的方法?
编辑 1
所以我更新了 xaml 以使用 datatrigger 方法,但我得到的错误是在类型 BindingExtension 中找不到 属性“RelativeSource”。
<ListView x:Name="SharedDocumentList"
HasUnevenRows="true"
>
<ListView.Resources>
<Style x:Key="PublicationStatus" TargetType="Label">
<Setter Property="FontFamily" Value="Segoe MDL2 Assets" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Tag, RelativeSource={RelativeSource Self}}"
Value="checkout">
<Setter Property="Text" Value="\uE701"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=Tag, RelativeSource={RelativeSource Self}}"
Value="published">
<Setter Property="Text" Value="\uE702"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ListView.Resources>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.ContextActions>
<MenuItem Text="Check In"
Clicked="CheckInFile"/>
<MenuItem Text="Check Out"
Clicked="CheckOutFile"/>
<MenuItem Text="Download"
Clicked="DownloadFile"/>
<MenuItem Text="Upload Local Copy"
Clicked="UploadFile"/>
</ViewCell.ContextActions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<Label Grid.Column="0" Text="{Binding Path=DriveItem.Name}"
FontSize="Small" />
<Label Grid.Column="1"
Style="{StaticResource PublicationStatus}"
Tag="{Binding PublicationStatus}" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
编辑 2
这是我尝试使用 ValueConverter。
下面是 class 的部分代码:
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class SPDocumentLibraryContentsPage : ContentPage
{
public string IconValue { get; set; }
public SPDocumentLibraryContentsPage()
{
InitializeComponent();
IconValue = "checkout";
//this.DataContext doesn't exist.
}
Xaml 页面上的 ListView 如下所示:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<Label Grid.Column="0" Text="{Binding Path=DriveItem.Name}"
FontSize="Small" />
<Label x:Name="testBlock" Grid.Column="2"
Text="{Binding IconValue,Converter={StaticResource IconValueConverter}}" FontFamily="Segoe MDL2 Assets" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
而且我能够创建 IconConverter class 没问题。 这里只是一个片段:
namespace GraphTutorial.Models
{
public class IconValueConverter : Xamarin.Forms.IValueConverter
{
}
编辑 3
为了得到工作的答案,我做了以下事情:
<Label Grid.Column="0" Text="{Binding Path=DriveItem.Name}" FontSize="Small" />
<Label Grid.Column="1" Text="{Binding Path=DriveItem.Publication.Level,Converter={StaticResource IconValueConverter}}" FontFamily="Segoe MDL2 Assets" />
有一种聪明的方法可以通过 Trigger
和 Tag
属性 来避免使用 IValueConverter
或从在 Style
.
在列表视图或根元素中
<ListView.Resources>
<Style x:Key="PublicationStatus" TargetType="Label">
<Setter Property="FontFamily" Value="Segoe MDL2 Assets" />
<Style.Triggers>
<Trigger Property="Tag"
Value="checkout">
<Setter Property="Text" Value="\uE701"/>
</Trigger>
<Trigger Property="Tag"
Value="published">
<Setter Property="Text" Value="\uE702"/>
</Trigger>
</Style.Triggers>
</Style>
</ListView.Resources>
然后在代码中:
<Label Grid.Column="1"
Style="{StaticResource PublicationStatus}"
Tag="{Binding PublicationStatus}" />
您也可以重复使用一种样式并将其放入某些 ResourceDictionary
.
警告。未测试。
您的应用似乎是 Xamarin UWP 应用,而不是本机 UWP 应用。
您也可以尝试在使用绑定时使用 ValueConverter。您需要做的是创建一个 ValueConverter class 并在 ValueConverter 中制定您自己的将不同字符串转换为不同图标的逻辑。 之后,您只需要在绑定中使用 ValueConverter 作为参数即可。
这是我在本机 UWP 应用程序中测试过的示例代码。它应该在 Xamarin UWP 应用程序中工作。您需要将 Textblock
替换为 Label
。
代码隐藏:
public class IconValueConverter: IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
string OutputValue ;
string textvalue = value as string;
if (textvalue.Equals("checkout"))
{
OutputValue = "\uE701";
}
else if (textvalue.Equals("published"))
{
OutputValue = "\uE702";
}
else
{
OutputValue = "\uE703";
}
return OutputValue;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
主页:
public string IconValue { get; set;}
public MainPage()
{
this.InitializeComponent();
IconValue = "checkout";
this.BindingContext = this;
}
Xaml代码:
<Page.Resources>
<local:IconValueConverter x:Key="IconValueConverter"/>
</Page.Resources>
<Grid>
<TextBlock x:Name="MyTextBlcok" Text="{Binding IconValue,Converter={StaticResource IconValueConverter}}" FontFamily="Segoe MDL2 Assets" />
</Grid>