【问题标题】:Xamarin.Forms ListviewXamarin.Forms 列表视图
【发布时间】:2016-12-31 10:17:38
【问题描述】:

我正在制作词汇应用程序并尝试在我的 Xamarin.Forms 列表视图中实现最喜欢的单词。

请看下面的截图

现在我使用硬代码而不是 MVVM 这是我的模型

namespace Mamtil.Models
{
    public class Word
    {
        public int Id { get; set; }
        public string word { get; set; }
        public string translation { get; set; }
        public string audio { get; set; }
        public bool favorite { get; set; }
        public string groupBy => translation[0].ToString().ToUpper();
    }
}

XAML

...
      <ViewCell>

        <StackLayout Orientation="Horizontal">
          <Button x:Name="FavoriteButton" Image="gray_star.png" BackgroundColor="#F5F5F5" Clicked="Favorite" BorderRadius="0" WidthRequest="45" CommandParameter="{Binding .}" /> 
          <Switch IsToggled="{Binding favorite}" WidthRequest="50"/>
          <StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand" Margin="5, 0, 0, 0">
            <Label Text="{Binding translation}">
              <Label.FontSize>
                <OnPlatform x:TypeArguments="x:Double" iOS="11" Android="18" />
              </Label.FontSize>
            </Label>
            <Label Text="{Binding word}" TextColor="#1565C0">
              <Label.FontSize>
                <OnPlatform x:TypeArguments="x:Double" iOS="11" Android="13" />
              </Label.FontSize>
            </Label>
          </StackLayout>

          <Button x:Name="SpeechButton" Image="ic_mic_black_24dp.png" BackgroundColor="#F5F5F5" Clicked="GoToSpeach" BorderRadius="0" WidthRequest="45" CommandParameter="{Binding Id}" />
        </StackLayout>

      </ViewCell>

所以问题是当我从数据库加载数据时,我如何初始化 FavoriteButton 的图像,如

<!-- Here switch is toggled or not depending on Binding value. I want to do something like this but with image of Button -->
<Switch IsToggled="{Binding favorite}">

在上面的代码中,它是硬编码的,但我想根据 Word.favorite 值进行更改。在运行时,我设法像这样更改图像

    async void Favorite(object sender, EventArgs e)
    {
        var b = (Button)sender;
        Word t = (Word)b.CommandParameter;
        //update in database
        await App.MamtilRepo.UpdateFavoriteAsync(t.Id);

        if (t.favorite)
            b.Image = "gray_star.png";
        else
            b.Image = "yellow_star.png";

        t.favorite = !t.favorite;
    }

举个例子:

...
// Some thing like
if(Word.favorite)
    Image = yellow_star.png;
else
    Image = gray_star.png;

我应该在代码中还是在 XAML 中做一些事情

我希望能清楚地描述我的问题。提前致谢

【问题讨论】:

    标签: xamarin.forms


    【解决方案1】:

    您必须使用 OnPropertyChanged() 方法,以便它为图像 Url 获取新值,并且您还应该设置绑定上下文。

    private bool _imageUrl;
    public bool ImageUrl
    {
        get { return _imageUrl; }
        set { _imageUrl = value; OnPropertyChanged(); }
    }
    

    并在您的构造函数中使用BindingContext = this;

    【讨论】:

      【解决方案2】:

      一个旧帖子,但这是另一种方法。 传统上,人们会为此使用转换器。 所以你的按钮 XAML 现在看起来像这样:

      <Button x:Name="FavoriteButton" Image="{Binding favorite, Converter={x:Static converter:FavoriteButton.Instance}}" BackgroundColor="#F5F5F5" Clicked="Favorite" BorderRadius="0" WidthRequest="45" CommandParameter="{Binding .}" />
      

      您需要在 XAML 文件的顶部添加一个关于转换器所在位置的引用,即

      xmlns:converter="clr-namespace:Mamtil.Converter;assembly=Interact.Client"
      

      你的转换器看起来像这样:

      namespace Mamtil.Converter {
      public class FavoriteButton : IValueConverter {
      // this Instance property just means your converter only needs to get created once, I saw it in a Xamarin sample.
          public static FavoriteButton Instance = new FavoriteButton(); 
          public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
              if (value == null) {
                  // only doing this because I've had encounters where an ImageSource has taken Exception at having null returned.
                  return ImageSource.FromFile("gray_star.png");
              }
              var fav = (bool)value;
              if (fav == true) { // redundant ==, but it makes it quite explicit for any future reader glancing over your code what you intend here.
                  return ImageSource.FromFile("yellow_star.png");
              }
              return ImageSource.FromFile("gray_star.png");
          }
      
          public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
              throw new NotImplementedException();
          }
      }
      }
      

      如果您使用的是嵌入式资源而不是本地文件,请参阅 Rohit 在 2016 年 8 月 24 日的回答中发布的链接,了解如何在转换器中使用这些资源。

      【讨论】:

        【解决方案3】:

        您可以将图像的Source 绑定到文件、Uri 或资源,从而设置要显示的图像。

        • FromFile - 需要可以在每个平台上解析的文件名或文件路径。
        • FromUri - 需要一个 Uri 对象,例如。新的 Uri("http://server.com/image.jpg") .
        • FromResource - 需要使用 Build Action:EmbeddedResource 嵌入应用程序或 PCL 中的图像文件的资源标识符。

        XAML:

         <Image Source="{Binding MyImage}" />
        

        视图模型:

        public ImageSource MyImage {get; set; }
        

        您可以阅读更多有关使用图片的信息here

        【讨论】:

          【解决方案4】:

          DataTrigger 或 Converter 是您问题的最佳解决方案。

          <Button Image="gray_star.png">
              <Button.Triggers>
                  <DataTrigger TargetType="Button" Binding="{Binding favorite}" Value="True">
                      <Setter Property="Image" Value="yellow_star.png" />
                  </DataTrigger>
              </Button.Triggers>
          </Button>
          

          【讨论】:

            猜你喜欢
            • 2016-05-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-10-17
            • 2016-03-14
            • 2019-07-20
            • 2018-04-08
            • 1970-01-01
            相关资源
            最近更新 更多