2017-04-11 76 views
1

你知道当你盯着某个东西足够长的时候它不再有意义了......我试图将listview项的背景属性绑定到它是否属于视图模型中的一个集合。以下是我的工作的简化版本:x:将ListView中的项绑定到ViewModel

<Grid> 

    <ListView x:Name="AirportListView" 
       SelectionMode="None" 
       IsItemClickEnabled="True" 
       ItemClick="AirportListView_ItemClick"> 

     <ListView.ItemTemplate> 

      <DataTemplate x:DataType="x:String"> 

       <Grid Padding="16"> 

        <TextBlock Text="{x:Bind}" /> 

       </Grid> 

      </DataTemplate> 

     </ListView.ItemTemplate>    

    </ListView> 

</Grid> 

和:

public sealed partial class MainPage : Page 
{ 
    public ObservableCollection<string> MyAirports { get; set; } = new ObservableCollection<string>(); 

    public MainPage() 
    { 
     this.InitializeComponent(); 

     AirportListView.ItemsSource = new List<string>() 
     { 
      "EDDB", 
      "LGIR", 
      "EHAM", 
      "LFPO", 
      "EGKK" 
     }; 
    } 

    private void AirportListView_ItemClick(object sender, ItemClickEventArgs e) 
    { 
     if (e.ClickedItem is string clickedAirport) 
     { 
      if (MyAirports.Contains(clickedAirport)) 
       MyAirports.Remove(clickedAirport); 
      else 
       MyAirports.Add(clickedAirport); 
     } 
    } 
} 

理想我想实现什么是网格的背景绑定在DataTemplate中,使其当一个项目是MyAirports的一部分时是不同的颜色。我只是无法弄清楚如何使用x:Bind或Binding来做到这一点。我可以想出更多的冗长的方法来实现同样的目标,但是想知道是否有更好的数据绑定解决方案。

任何想法将不胜感激!

回答

0

你需要做的是去的ItemsSource更丰富的类不只是一个字符串的集合。它应该包含属性IsMyAirport,然后它可以绑定到每个ListViewItem以及更新其背景。

<Page ... 
    xmlns:local="using:UwpQuestions.Views" 
    xmlns:common="using:UwpQuestions.Common"> 
    <Page.Resources> 
     <common:MyBgConverter x:Key="myBgConverter"/> 
    </Page.Resources> 

<Grid> 
    <ListView x:Name="AirportList" 
      SelectionMode="None" 
      IsItemClickEnabled="True" 
      HorizontalContentAlignment="Stretch" 
      ItemsSource="{x:Bind Airports}" 
      ItemClick="AirportListView_ItemClick"> 
     <ListView.ItemTemplate> 
      <DataTemplate x:DataType="local:AirportItem"> 
       <Grid Padding="16" Width="150" Background="{x:Bind IsMyAirport, Mode=OneWay, Converter={StaticResource myBgConverter}}"> 
        <Grid.ColumnDefinitions> 
         <ColumnDefinition Width="*"/> 
        </Grid.ColumnDefinitions> 
        <TextBlock Text="{x:Bind Name}" /> 
       </Grid> 
      </DataTemplate> 
     </ListView.ItemTemplate> 
    </ListView> 
</Grid> 
</Page> 

随着后面以下代码:

public sealed partial class AirportListView : Page 
{ 
    public ObservableCollection<string> MyAirports { get; set; } = new ObservableCollection<string>(); 
    public ObservableCollection<AirportItem> Airports { get; set; } 

    public AirportListView() 
    { 
     this.InitializeComponent(); 
     Airports = new ObservableCollection<AirportItem> 
     { 
      new AirportItem {Name = "EDDB"}, 
      new AirportItem {Name = "LGIR"}, 
      new AirportItem {Name = "LFPO"}, 
      new AirportItem {Name = "EGKK"} 
     }; 
    } 

    private void AirportListView_ItemClick(object sender, ItemClickEventArgs e) 
    { 
     if (e.ClickedItem is AirportItem clickedAirport) 
     { 
      if (MyAirports.Contains(clickedAirport.Name)) 
      { 
       MyAirports.Remove(clickedAirport.Name); 
       clickedAirport.IsMyAirport = false; 
      } 
      else 
      { 
       MyAirports.Add(clickedAirport.Name); 
       clickedAirport.IsMyAirport = true; 
      } 
     } 
    } 
} 

public class AirportItem : BindableBase 
{ 
    private string _name; 
    public string Name 
    { 
     get { return _name; } 
     set { SetProperty<string>(ref _name, value); } 
    } 

    private bool _isMyAirport = false; 
    public bool IsMyAirport 
    { 
     get { return _isMyAirport; } 
     set { SetProperty<bool>(ref _isMyAirport, value); } 
    } 
} 

AirportItem使用BindableBase通知时属性的的ListView在类变化。它实现INotifyPropertyChanged。如果你不熟悉它,你应该阅读XAML数据绑定。

而且,它还使用MyBgConverter(即Laith定义的)将bool值更改为不同的背景色。

最后,通过类的IsMyAirport属性,您可能不需要单独的MyAirports字符串列表。我没有删除它,因为我不确定你是否将它用于别的东西。但是您的AirportListView_ItemClick中的逻辑可以更改为仅使用IsMyAirport布尔而不是MyAirports列表。

+0

感谢佩德罗,是的,这是我实际尝试做的一个简化版本,但是我已经设法做到了这一点,就像你说'烘烤'一个名为IsMyAirport的属性到原来的类,并确保保持更新的变化到收藏。现在将尝试让它在我的应用程序中工作。非常感谢! – varyamereon

-1

创建转换boolSolidColorBrush一个转换器,并使用在具有约束力。

<ListView Background="{x:Bind IsPartOfMyAirports, Converter={StaticResource MyBgConverter}}"> 
... 
</ListView> 

您的视图模型将负责通知IsPartOfMyAirports的更改。

你的转换器可以是这个样子:

public class MyBgConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, string language) 
    { 
     var b = (bool)value; 
     var color = b ? Colors.Yellow : Colors.Green; 

     return new SolidColorBrush(color); 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, string language) 
    { 
     throw new NotImplementedException(); 
    } 
} 
+0

嗨赖斯,感谢您的建议。这个想法将绑定每个单独项目的背景,所以我不确定在哪里创建'IsPartOfMyAirports',以便它可以由每个项目更新。 – varyamereon

相关问题