Xaml 在listview MVVM中绑定复选框
我正在尝试按如下方式绑定复选框,但当我单击它时,它甚至没有保持选中状态。下面是映射到db的我的模型。我希望使用选中的复选框获取所选项目,以便最终获取成本字段。我已尝试从 由Matt Baxter Reynolds和Iris Classon编写。我已更新代码以匹配@Arnaud提供的答案。复选框不会保持选中状态,但单击单选按钮时按钮的可见性会发生变化 型号服务项目Xaml 在listview MVVM中绑定复选框,xaml,listview,windows-phone-8,mvvm,Xaml,Listview,Windows Phone 8,Mvvm,我正在尝试按如下方式绑定复选框,但当我单击它时,它甚至没有保持选中状态。下面是映射到db的我的模型。我希望使用选中的复选框获取所选项目,以便最终获取成本字段。我已尝试从 由Matt Baxter Reynolds和Iris Classon编写。我已更新代码以匹配@Arnaud提供的答案。复选框不会保持选中状态,但单击单选按钮时按钮的可见性会发生变化 型号服务项目 public class ServiceItem:ModelItem { // key field.
public class ServiceItem:ModelItem
{
// key field...
[AutoIncrement(), PrimaryKey(), JsonIgnore]
public int Id { get; set; }
// other fields...
[Unique, JsonProperty("id")]
public int NativeId { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
public decimal Cost
{
get
{
return GetValue<decimal>();
}
set
{
SetValue(value);
}
}
[JsonIgnore] //prefer not to have it on db has no value
public bool IsSelected
{
get
{
return GetValue<bool>();
}
set
{
SetValue(value);
}
}
public ServiceItem()
{
}
}
public abstract class ModelItem : INotifyPropertyChanged
{
private Dictionary<string, object> Values { get; set; }
protected ModelItem()
{
this.Values = new Dictionary<string, object>();
}
public event PropertyChangedEventHandler PropertyChanged;
protected T GetValue<T>([CallerMemberName] string name = null)
{
if (this.Values.ContainsKey(name))
return (T)this.Values[name];
else
return default(T);
}
protected void SetValue(object value, [CallerMemberName] string name = null)
{
// set...
this.Values[name] = value;
// notify...
this.OnPropertyChanged(new PropertyChangedEventArgs(name));
}
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
this.OnPropertyChanged(new PropertyChangedEventArgs(name));
}
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, e);
}
}
视图模型接口Iviewmodel
public class ServicesPageViewModel : ViewModel, IServicesPageViewModel
{
public ObservableCollection<ServiceItem> Items { get; private set; }
public ICommand ContinueCommand { get; private set; }
public ServicesPageViewModel()
{
}
public override void Initialize(IViewModelHost host)
{
base.Initialize(host);
// setup...
this.Items = new ObservableCollection<ServiceItem>();
this.ContinueCommand = new DelegateCommand((args) => GetSelected(args as CommandExecutionContext));
}
}
<ListView ItemsSource="{Binding Items}"
IsItemClickEnabled="true"
Margin="10,10,10,0" TabIndex="1">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"></ColumnDefinition>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<CheckBox Content="{Binding Name}"
BorderBrush="{ThemeResource AppBarBackgroundThemeBrush}"
IsChecked="{Binding IsSelected, Mode=TwoWay}"></CheckBox>
<Button Content="{Binding Cost, Mode=TwoWay}"
public abstract class ViewModel : ModelItem, IViewModel
{
// somewhere to hold the host...
protected IViewModelHost Host { get; private set; }
//other code omitted
}
public interface IViewModel : INotifyPropertyChanged
{
void Initialize(IViewModelHost host);
//other code omitted
}
ModelItem
public class ServiceItem:ModelItem
{
// key field...
[AutoIncrement(), PrimaryKey(), JsonIgnore]
public int Id { get; set; }
// other fields...
[Unique, JsonProperty("id")]
public int NativeId { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
public decimal Cost
{
get
{
return GetValue<decimal>();
}
set
{
SetValue(value);
}
}
[JsonIgnore] //prefer not to have it on db has no value
public bool IsSelected
{
get
{
return GetValue<bool>();
}
set
{
SetValue(value);
}
}
public ServiceItem()
{
}
}
public abstract class ModelItem : INotifyPropertyChanged
{
private Dictionary<string, object> Values { get; set; }
protected ModelItem()
{
this.Values = new Dictionary<string, object>();
}
public event PropertyChangedEventHandler PropertyChanged;
protected T GetValue<T>([CallerMemberName] string name = null)
{
if (this.Values.ContainsKey(name))
return (T)this.Values[name];
else
return default(T);
}
protected void SetValue(object value, [CallerMemberName] string name = null)
{
// set...
this.Values[name] = value;
// notify...
this.OnPropertyChanged(new PropertyChangedEventArgs(name));
}
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
this.OnPropertyChanged(new PropertyChangedEventArgs(name));
}
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, e);
}
}
公共抽象类ModelItem:INotifyPropertyChanged
{
专用字典值{get;set;}
受保护的模型项()
{
this.Values=newdictionary();
}
公共事件属性更改事件处理程序属性更改;
受保护的T GetValue([CallerMemberName]字符串名称=null)
{
if(this.Values.ContainsKey(name))
返回(T)this.Values[name];
其他的
返回默认值(T);
}
受保护的void SetValue(对象值,[CallerMemberName]字符串名称=null)
{
//设置。。。
this.Values[name]=值;
//通知。。。
此.OnPropertyChanged(新PropertyChangedEventArgs(名称));
}
受保护的void OnPropertyChanged([CallerMemberName]字符串名称=null)
{
此.OnPropertyChanged(新PropertyChangedEventArgs(名称));
}
PropertyChanged上受保护的虚拟无效(PropertyChangedEventArgs e)
{
if(this.PropertyChanged!=null)
本。财产变更(本,e);
}
}
您需要在类ServiceItem
上实现INotifyPropertyChanged
,否则在更新值时将永远不会引发任何事件
以下是我的观点代码。我添加了一个转换器,仅在选择项目时显示成本:
<Page
x:Class="App4.CheckBoxPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App4"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
>
<Page.Resources>
<local:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Page.Resources>
<ListView ItemsSource="{Binding Items}"
IsItemClickEnabled="true"
Margin="10,10,10,0" TabIndex="1">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"></ColumnDefinition>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<CheckBox Content="{Binding Name}"
BorderBrush="{ThemeResource AppBarBackgroundThemeBrush}"
IsChecked="{Binding IsSelected, Mode=TwoWay}"></CheckBox>
<Button Content="{Binding Cost, Mode=TwoWay}" Visibility="{Binding IsSelected, Converter={StaticResource BooleanToVisibilityConverter}}" Grid.Column="1"></Button>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Page>
您需要在类
ServiceItem
上实现INotifyPropertyChanged
,否则在更新值时将永远不会引发任何事件
以下是我的观点代码。我添加了一个转换器,仅在选择项目时显示成本:
<Page
x:Class="App4.CheckBoxPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App4"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
>
<Page.Resources>
<local:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Page.Resources>
<ListView ItemsSource="{Binding Items}"
IsItemClickEnabled="true"
Margin="10,10,10,0" TabIndex="1">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"></ColumnDefinition>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<CheckBox Content="{Binding Name}"
BorderBrush="{ThemeResource AppBarBackgroundThemeBrush}"
IsChecked="{Binding IsSelected, Mode=TwoWay}"></CheckBox>
<Button Content="{Binding Cost, Mode=TwoWay}" Visibility="{Binding IsSelected, Converter={StaticResource BooleanToVisibilityConverter}}" Grid.Column="1"></Button>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Page>
我已经在接口IViewModel上更改了Inotifypropertychanged。为了完整起见,我添加它@AmaudYes,但您仍然需要在ViewModel使用的类上实现
Inotifypropertychanged
。ServicesPageViewModel实现了ViewModel,它实现了IViewModel,而IViewModel实现了InotifyPropertyChangedInes,但这还不够。例如,检查此模型类:。它扩展了ModelItem
类,以便为以下属性实现INotifyPropertyChanged
:Description和Active。我已在回答中更新了ServiceItem类以使用您的模型类。例如,活动属性声明为public bool Active{get{return this.GetValue();}内部集{this.SetValue(value);}}
适用于阅读此内容并犯同样愚蠢错误的任何人。复选框中的复选框在白色背景上为白色,前景色设置为黑色只会使文本内容变为黑色,而不是勾号本身。#MyRookeeMissMakeS101我已在我的界面IViewModel上更改了InotifyProperty。为了完整性,我添加它@AmaudYes,但是您仍然需要在ViewModel使用的类上实现INotifyPropertyChanged
。ServicesPageViewModel实现了ViewModel,后者实现了IViewModel,后者实现了InotifyPropertyChangedInes,但这还不够。例如,检查此模型类:。它扩展了ModelItem
类,以便为以下属性实现INotifyPropertyChanged
:Description和Active。我已在回答中更新了ServiceItem类以使用您的模型类。例如,活动属性声明为public bool Active{get{return this.GetValue();}内部集{this.SetValue(value);}}
适用于阅读此内容并犯同样愚蠢错误的任何人。复选框中的复选框在白色背景上为白色,而前景色设置为黑色只会使文本内容变为黑色,而不会使勾号本身变为黑色。#MyRookie出错101