C# x:将ListView中的项绑定到ViewModel
你知道,当你盯着某件事看得够久的时候,它就不再有意义了。。。我试图将listview项的background属性绑定到它是否是viewmodel中集合的一部分。以下是我正在使用的简化版本:C# x:将ListView中的项绑定到ViewModel,c#,listview,uwp,C#,Listview,Uwp,你知道,当你盯着某件事看得够久的时候,它就不再有意义了。。。我试图将listview项的background属性绑定到它是否是viewmodel中集合的一部分。以下是我正在使用的简化版本: <Grid> <ListView x:Name="AirportListView" SelectionMode="None" IsItemClickEnabled="True" ItemClick=
<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>
以及:
公共密封部分类主页面:第页
{
公共ObservableCollection MyAirports{get;set;}=new ObservableCollection();
公共主页()
{
this.InitializeComponent();
AirportListView.ItemsSource=新列表()
{
“EDDB”,
“LGIR”,
“艾哈姆”,
“LFPO”,
“EGKK”
};
}
private void AirportListView_ItemClick(对象发送者,ItemClickEventArgs e)
{
如果(例如ClickedItem是字符串clickedAirport)
{
if(MyAirports.Contains(单击机场))
我的机场。删除(单击机场);
其他的
MyAirports.Add(单击机场);
}
}
}
理想情况下,我希望实现的是在datatemplate中绑定网格的背景,以便当项目是MyAirports的一部分时,它是不同的颜色。我只是不知道如何使用x:Bind或Binding来实现这一点。我可以想出一些更冗长的方法来实现同样的目标,但我想知道是否有一种更优雅的数据绑定解决方案
任何想法都将不胜感激
将创建一个转换器,将
bool
转换为SolidColorBrush
,并在绑定中使用它
<ListView Background="{x:Bind IsPartOfMyAirports, Converter={StaticResource MyBgConverter}}">
...
</ListView>
您需要使到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); }
}
}
公共密封部分类AirportListView:第页
{
公共ObservableCollection MyAirports{get;set;}=new ObservableCollection();
公共可观测收集机场{get;set;}
公共机场列表视图()
{
this.InitializeComponent();
机场=新的可观测集合
{
新的AirportItem{Name=“EDDB”},
新的AirportItem{Name=“LGIR”},
新的AirportItem{Name=“LFPO”},
新机场项目{Name=“EGKK”}
};
}
private void AirportListView_ItemClick(对象发送者,ItemClickEventArgs e)
{
如果(如ClickedItem是AirportItem clickedAirport)
{
if(MyAirports.Contains(clickedAirport.Name))
{
MyAirports.Remove(单击机场名称);
单击eDairport.IsMyAirport=false;
}
其他的
{
添加(单击机场名称);
单击edairport.IsMyAirport=true;
}
}
}
}
公共类AirportItem:BindableBase
{
私有字符串\u名称;
公共字符串名
{
获取{return\u name;}
set{SetProperty(ref_name,value);}
}
private bool_isMyAirport=false;
公共图书馆伊斯梅尔机场
{
获取{return\u isMyAirport;}
set{SetProperty(ref_isMyAirport,value);}
}
}
AirportItem使用BindableBase通知ListView类中的属性何时更改。它实现INotifyPropertyChanged。如果您不熟悉它,您应该阅读XAML数据绑定
而且,它还使用MyBgConverter(Laith定义的)将布尔值更改为不同的背景色
最后,使用类上的IsMyAirport属性,您可能不需要单独的MyAirports字符串列表。我没有移除它,因为我不确定你是否在用它做其他用途。但是您在AirportListView\u ItemClick中的逻辑可以更改为只使用IsMyAirportBool而不是MyAirports列表。Hi-Laith,谢谢您的建议。我们的想法是绑定每个项目的背景,因此我不确定在哪里创建
IsPartOfMyAirports
,以便每个项目都可以更新。谢谢Pedro,是的,这是我实际尝试的简化版本,但是,正如您所说,我已经成功地将一个名为IsMyAirport的属性“烘焙”到原始类中,并确保该属性随着集合的更改而保持更新。现在,我将尝试让它在我的应用程序中工作。非常感谢!
<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); }
}
}