2015-10-16 75 views
4

我有一個關於在Xamarin.Forms 列表視圖問題綁定列表視圖我成功地與一些項目,但我想更改選定單元格的背景顏色我如何在Xamarin.Forms更改背景顏色將selectedItem列表視圖

做到這一點

我利用

var cell = DataTemplate(typeof(ImageCell)); 

ListView listView = new ListView 
{ 
    SeparatorColor = Color.Green, 
    ItemsSource = ListlvData, 
    ItemTemplate = cell, // Set the ImageCell to the item templatefor the listview 
}; 
+0

你見過這樣的:http://forums.xamarin.com/discussion/19500/how-to-change-background-color-on-a-listview –

+0

多數民衆贊成不是什麼即時通訊尋找我想要改變顏色上藍色的默認是藍色 –

+0

我相信你將不得不在風格的實際平臺代碼。 – Johan

回答

7

編輯2:

有時,如果我遇到了奇怪的問題,在我的ViewCellBackgroundColor從未變回原來的顏色,所以我已經開始做這個改變,而不是顏色:

cell.Tapped += async (sender, args) => { 
    cell.View.BackgroundColor = Color.Red; 

#pragma warning disable 4014 //These pragma's are only needed if your Tapped is being assigned an async anonymous function and muffles the compiler warning that you did not await Task.Run() which you do not want to fire and forget it 

    Task.Run(async() => {  //Change the background color back after a small delay, no matter what happens 
     await Task.Delay(300); //Or how ever long to wait 

     Device.BeginInvokeOnMainThread(() => cell.View.BackgroundColor = Color.Default); //Turn it back to the default color after your event code is done 
    }); 

#pragma warning restore 4014 

    await OnListViewTextCellTapped(cell); //Run your actual `Tapped` event code 

}; 

編輯:

爲了下面的代碼添加到ListView.DataTemplate,你會想要做的事像這樣:

ListView listView = new ListView { 
    SeparatorColor = Color.Green, 
    ItemsSource = ListlvData 
}; 

listView.ItemTemplate = new DataTemplate(() => { 
    ViewCell cell = new ViewCell(); 

    cell.Tapped += (sender, args) => { 
     cell.View.BackgroundColor = Color.Red; 
     OnListViewTextCellTapped(cell);   //Run your actual `Tapped` event code 
     cell.View.BackgroundColor = Color.Default; //Turn it back to the default color after your event code is done 
    }; 

    cell.View = new Image(); 

    return cell; 
}); 

要更改Tapped的背景顏色,你將需要使用一個ViewCell和一個Image控件,因爲ImageCell默認不支持BackgroundColor

我把StackLayoutViewCell內,但隨後在Tapped事件,我改變ViewCell.ViewBackgroundColor,就像這樣:

ViewCell cell = new ViewCell(); 

cell.Tapped += (sender, args) => { 
    cell.View.BackgroundColor = Color.Red; 
    OnListViewTextCellTapped(cell);   //Run your actual `Tapped` event code 
    cell.View.BackgroundColor = Color.Default; //Turn it back to the default color after your event code is done 
}; 
+0

如何將此添加到DataTemplateLayout –

+0

@StefanvandeLaarschot - 檢查編輯 – hvaughan3

+0

thnx男人!幫我分配:) –

5

我知道這已經很長一段時間前答覆,但想通我對於任何可能在這個問題中碰到的人尋找更多的MVVM友好的方式來爲此添加更多信息。我最終得出了以下結論,如果他們如此傾向,有人會希望有用。

您將需要一個值轉換器,如以下幾點:

public class UseColorIfConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     return (bool)value ? parameter : Color.Transparent; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

轉換器只是如果提供的參數計算結果爲true返回相應Color。我也註冊了該轉換器在我的App.xaml(這不得不手動創建)一個靜態資源,即:

<?xml version="1.0" encoding="utf-8" ?> 
<forms:FormsApplication xmlns="http://xamarin.com/schemas/2014/forms" 
     xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
     xmlns:forms="clr-namespace:Caliburn.Micro.Xamarin.Forms;assembly=Caliburn.Micro.Platform.Xamarin.Forms" 
     x:Class="Path.To.Application.App" 
     xmlns:converters="clr-namespace:Path.To.Converters.Namespace;assembly=Converter.Assembly"> 
    <Application.Resources> 
     <converters:UseColorIfConverter x:Key="UseColorIf"></converters:UseColorIfConverter> 
    </Application.Resources> 
</forms:FormsApplication> 

請注意,我用的卡利微,但同樣會默認Xamarin合作.Forms.Application類也是如此。然後

轉換器和潛在的綁定的使用將是以下:

<ListView ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}"> 
    <ListView.ItemTemplate> 
     <DataTemplate> 
      <ViewCell> 
       <ContentView BackgroundColor="{Binding Path=Selected, Converter={StaticResource UseColorIf}, ConverterParameter={x:StaticResource ListSelectionColor}}" ...> 
        <!--Display--> 
       </ContentView> 
      </ViewCell> 
     </DataTemplate> 
    </ListView.ItemTemplate> 
</ListView> 

這然後允許你綁定針對其指示它是否被選中或未被每一視圖模型的屬性。此屬性必須保持同步,但很輕鬆地通過訂閱屬性來完成改變的事件。例如:

public class MenuViewModel : Screen 
{ 
    public BindableCollection<SectionViewModel> Items { get; }  

    public MenuViewModel(IEnumerable<SectionViewModel> sections) 
    { 
     Items = new BindableCollection<SectionViewModel>(sections); 
     PropertyChanged += OnPropertyChanged; 
    } 

    private SectionViewModel _selectedItem; 

    public SectionViewModel SelectedItem 
    { 
     get { return _selectedItem; } 
     set 
     { 
      if (_selectedItem == value) 
       return; 
      _selectedItem = value; 
      NotifyOfPropertyChange(nameof(SelectedItem)); 
     } 
    } 

    private void OnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs) 
    { 
     if (propertyChangedEventArgs.PropertyName == nameof(SelectedItem)) 
     { 
      foreach (var item in Items) 
      { 
       item.Selected = item == SelectedItem; 
      } 
     } 
    } 
} 

也有這樣做後,剩下的一個瑣碎的事情,那就是在每個平臺上使用的默認渲染。我沒有檢查Android,但至少在IOS你仍然會得到一個灰色邊框所以下面只是刪除它:

using UIKit; 
using Xamarin.Forms; 
using Xamarin.Forms.Platform.iOS; 

[assembly: ExportRenderer(typeof(ViewCell), typeof(CustomListViewCellRenderer))] 

namespace My.Awesome.Ios.Client.Renderers 
{ 
    class CustomListViewCellRenderer : ViewCellRenderer 
    { 

     public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv) 
     { 
      var cell = base.GetCell(item, reusableCell, tv); 

      cell.SelectionStyle = UITableViewCellSelectionStyle.None; 
      return cell; 
     } 
    } 
}