如何将 viewmodel 变量绑定到 xamarin 形式的 ObservableCollection 项?
how to bind a viewmodel variable to ObservableCollection items in xamarin form?
我有一个任务列表,我需要将布尔变量绑定到它的项目。
任务对象包含一个 completedDate 属性,如果它有值,则将任务定义为已完成。
在视图中,我需要检查按钮文本是否具有显示文本的值:“标记为不完整”
----任务对象-----
public class ProjectTaskLineItemSummary
{
public int TenantId { get; set; }
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public decimal? CostMultiplier { get; set; }
public DateTimeOffset? CompletedDate { get; set; }
public int? CompletedByUserId { get; set; }
}
--------视图模型--------
viewmodel()
{
public ObservableCollection<ProjectTaskLineItemSummary> Tasks { get; set; }
...
bool isCompleted;
public bool IsCompleted
{
get {
return isCompleted;
}
set
{
isCompleted = value;
OnPropertyChanged();
}
}
}
-----查看----
<CollectionView Grid.Row="1" ItemsSource="{Binding Tasks}" x:Name="List3">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid>
<Frame
Margin="0,10"
Padding="10"
BackgroundColor="{StaticResource PrimaryWhite}"
BorderColor="{StaticResource PrimaryLightGray}"
CornerRadius="10"
HasShadow="False">
<Grid RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto" RowSpacing="15">
<StackLayout HorizontalOptions="EndAndExpand" Orientation="Horizontal">
<Image
HeightRequest="20"
Source="iconCalender.png"
WidthRequest="20" />
<Label
FontFamily="{StaticResource MeduimFont}"
Style="{StaticResource LabelMedium}"
Text="{Binding CompletedDate,StringFormat='{0:MMMM dd, yyyy}'}"
TextColor="{StaticResource PrimaryBlack}"
/>
</StackLayout>
</StackLayout>
<BoxView
Grid.Row="1"
HeightRequest="1"
Color="{StaticResource PrimaryLightGray}" />
<Label
Grid.Row="2"
Style="{StaticResource LabelMedium}"
Text="{Binding Name}"
TextColor="{StaticResource PrimaryBlack}" />
<Button
x:Name="lstbtnMarkasComplite"
Grid.Row="5"
Padding="15,0"
Clicked="MarkTaskAsCompletedClicked"
CornerRadius="20"
FontSize="{StaticResource Font12}"
HeightRequest="40"
CommandParameter="{Binding Id}"
HorizontalOptions="CenterAndExpand"
Style="{StaticResource ButtonPurple}"
Text="Mark as Completed" >
<Button.Triggers>
<DataTrigger TargetType="Button" Binding="{Binding IsCompleted}" Value="True">
<Setter Property="Text" Value="Mark Task as In Completed"/>
</DataTrigger>
</Button.Triggers>
</Button>
</Grid>
</Frame>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
我尝试在视图模型中分配它,如下所示,但它不起作用:
public override async Task InitializeAsync(object navigationData)
{
await SetBusyAsync(async () =>
{
...
Tasks = ObjectMapper.Map<ObservableCollection<ProjectTaskLineItemSummary>>(project.TaskLineItems);
foreach (var task in Tasks)
{
isCompleted = task.CompletedDate.HasValue ? true : false;
}
RaisePropertyChanged(() => Model);
RaisePropertyChanged(() => Notes);
RaisePropertyChanged(() => Files);
RaisePropertyChanged(() => Tasks);
});
}
这可以简单地通过按钮的Binding
Text
属性然后根据CompletedDate
动态设置按钮的Text
来实现实体的。
以下是供您参考的代码片段:
型号:
ProjectTaskLineItemSummary.cs
public class ProjectTaskLineItemSummary
{
public int TenantId { get; set; }
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public decimal? CostMultiplier { get; set; }
public DateTimeOffset? CompletedDate { get; set; }
public int? CompletedByUserId { get; set; }
public string CompletedButton { get; set; }
}
查看:
<CollectionView ItemsSource="{Binding Tasks}" x:Name="List3" Background="aqua">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid>
<Frame Margin="0,10" Padding="10" HasShadow="False">
<Grid RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto" RowSpacing="15">
<StackLayout HorizontalOptions="EndAndExpand" Orientation="Horizontal">
<Image HeightRequest="30" Source="XamarinLogo.png" WidthRequest="80" />
<Label x:Name="mydate" Text="{Binding CompletedDate,StringFormat='{0:MMMM dd, yyyy}'}" TextColor="Black"/>
</StackLayout>
<BoxView Grid.Row="1" HeightRequest="1" Color="Black" />
<Label Grid.Row="2" Text="{Binding Name}" TextColor="Black" />
<Button Grid.Row="5" x:Name="lstbtnMarkasComplite" Padding="15,0"
Clicked="MarkTaskAsCompletedClicked"
CornerRadius="20"
Text="{Binding CompletedButton}"
FontSize="Medium"
HeightRequest="40"
CommandParameter="{Binding Id}"
HorizontalOptions="CenterAndExpand">
</Button>
</Grid>
</Frame>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
ViewModel:
public class PageViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public ObservableCollection<ProjectTaskLineItemSummary> Tasks { get; set; }
bool isCompleted { get; set; }
public bool IsCompleted
{
get => isCompleted;
set
{
isCompleted = value;
PropertyChanged?.Invoke(this,
new PropertyChangedEventArgs(nameof(IsCompleted)));
}
}
string completed { get; set; }
public String CompletedButton
{
get => completed;
set
{
completed = value;
PropertyChanged?.Invoke(this,
new PropertyChangedEventArgs(nameof(CompletedButton)));
}
}
public PageViewModel()
{
Tasks = new ObservableCollection<ProjectTaskLineItemSummary>()
{
new ProjectTaskLineItemSummary(){TenantId = 1, Id =1, Name = "jobs ", Description= "jjjj",CostMultiplier=1 ,CompletedDate =DateTime.UtcNow, CompletedByUserId=1 ,CompletedButton = ""},
new ProjectTaskLineItemSummary(){TenantId = 2, Id =2, Name = "james ",Description= "aaaa",CostMultiplier=2 , CompletedByUserId=2,CompletedButton = "" },
new ProjectTaskLineItemSummary(){TenantId = 3, Id =3, Name = "rollex ",Description= "rrrr",CostMultiplier=3 ,CompletedDate =DateTime.UtcNow, CompletedByUserId=3 ,CompletedButton = ""}
};
setButtonIsCompleted();
}
private void setButtonIsCompleted()
{
foreach (var task in Tasks)
{
if (task.CompletedDate == null)
{
task.CompletedButton = "Mark Task as Completed";
}
else
{
task.CompletedButton = "Mark Task as inCompleted";
}
}
}
}
我有一个任务列表,我需要将布尔变量绑定到它的项目。 任务对象包含一个 completedDate 属性,如果它有值,则将任务定义为已完成。 在视图中,我需要检查按钮文本是否具有显示文本的值:“标记为不完整”
----任务对象-----
public class ProjectTaskLineItemSummary
{
public int TenantId { get; set; }
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public decimal? CostMultiplier { get; set; }
public DateTimeOffset? CompletedDate { get; set; }
public int? CompletedByUserId { get; set; }
}
--------视图模型--------
viewmodel()
{
public ObservableCollection<ProjectTaskLineItemSummary> Tasks { get; set; }
...
bool isCompleted;
public bool IsCompleted
{
get {
return isCompleted;
}
set
{
isCompleted = value;
OnPropertyChanged();
}
}
}
-----查看----
<CollectionView Grid.Row="1" ItemsSource="{Binding Tasks}" x:Name="List3">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid>
<Frame
Margin="0,10"
Padding="10"
BackgroundColor="{StaticResource PrimaryWhite}"
BorderColor="{StaticResource PrimaryLightGray}"
CornerRadius="10"
HasShadow="False">
<Grid RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto" RowSpacing="15">
<StackLayout HorizontalOptions="EndAndExpand" Orientation="Horizontal">
<Image
HeightRequest="20"
Source="iconCalender.png"
WidthRequest="20" />
<Label
FontFamily="{StaticResource MeduimFont}"
Style="{StaticResource LabelMedium}"
Text="{Binding CompletedDate,StringFormat='{0:MMMM dd, yyyy}'}"
TextColor="{StaticResource PrimaryBlack}"
/>
</StackLayout>
</StackLayout>
<BoxView
Grid.Row="1"
HeightRequest="1"
Color="{StaticResource PrimaryLightGray}" />
<Label
Grid.Row="2"
Style="{StaticResource LabelMedium}"
Text="{Binding Name}"
TextColor="{StaticResource PrimaryBlack}" />
<Button
x:Name="lstbtnMarkasComplite"
Grid.Row="5"
Padding="15,0"
Clicked="MarkTaskAsCompletedClicked"
CornerRadius="20"
FontSize="{StaticResource Font12}"
HeightRequest="40"
CommandParameter="{Binding Id}"
HorizontalOptions="CenterAndExpand"
Style="{StaticResource ButtonPurple}"
Text="Mark as Completed" >
<Button.Triggers>
<DataTrigger TargetType="Button" Binding="{Binding IsCompleted}" Value="True">
<Setter Property="Text" Value="Mark Task as In Completed"/>
</DataTrigger>
</Button.Triggers>
</Button>
</Grid>
</Frame>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
我尝试在视图模型中分配它,如下所示,但它不起作用:
public override async Task InitializeAsync(object navigationData)
{
await SetBusyAsync(async () =>
{
...
Tasks = ObjectMapper.Map<ObservableCollection<ProjectTaskLineItemSummary>>(project.TaskLineItems);
foreach (var task in Tasks)
{
isCompleted = task.CompletedDate.HasValue ? true : false;
}
RaisePropertyChanged(() => Model);
RaisePropertyChanged(() => Notes);
RaisePropertyChanged(() => Files);
RaisePropertyChanged(() => Tasks);
});
}
这可以简单地通过按钮的Binding
Text
属性然后根据CompletedDate
动态设置按钮的Text
来实现实体的。
以下是供您参考的代码片段:
型号: ProjectTaskLineItemSummary.cs
public class ProjectTaskLineItemSummary
{
public int TenantId { get; set; }
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public decimal? CostMultiplier { get; set; }
public DateTimeOffset? CompletedDate { get; set; }
public int? CompletedByUserId { get; set; }
public string CompletedButton { get; set; }
}
查看:
<CollectionView ItemsSource="{Binding Tasks}" x:Name="List3" Background="aqua">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid>
<Frame Margin="0,10" Padding="10" HasShadow="False">
<Grid RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto" RowSpacing="15">
<StackLayout HorizontalOptions="EndAndExpand" Orientation="Horizontal">
<Image HeightRequest="30" Source="XamarinLogo.png" WidthRequest="80" />
<Label x:Name="mydate" Text="{Binding CompletedDate,StringFormat='{0:MMMM dd, yyyy}'}" TextColor="Black"/>
</StackLayout>
<BoxView Grid.Row="1" HeightRequest="1" Color="Black" />
<Label Grid.Row="2" Text="{Binding Name}" TextColor="Black" />
<Button Grid.Row="5" x:Name="lstbtnMarkasComplite" Padding="15,0"
Clicked="MarkTaskAsCompletedClicked"
CornerRadius="20"
Text="{Binding CompletedButton}"
FontSize="Medium"
HeightRequest="40"
CommandParameter="{Binding Id}"
HorizontalOptions="CenterAndExpand">
</Button>
</Grid>
</Frame>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
ViewModel:
public class PageViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public ObservableCollection<ProjectTaskLineItemSummary> Tasks { get; set; }
bool isCompleted { get; set; }
public bool IsCompleted
{
get => isCompleted;
set
{
isCompleted = value;
PropertyChanged?.Invoke(this,
new PropertyChangedEventArgs(nameof(IsCompleted)));
}
}
string completed { get; set; }
public String CompletedButton
{
get => completed;
set
{
completed = value;
PropertyChanged?.Invoke(this,
new PropertyChangedEventArgs(nameof(CompletedButton)));
}
}
public PageViewModel()
{
Tasks = new ObservableCollection<ProjectTaskLineItemSummary>()
{
new ProjectTaskLineItemSummary(){TenantId = 1, Id =1, Name = "jobs ", Description= "jjjj",CostMultiplier=1 ,CompletedDate =DateTime.UtcNow, CompletedByUserId=1 ,CompletedButton = ""},
new ProjectTaskLineItemSummary(){TenantId = 2, Id =2, Name = "james ",Description= "aaaa",CostMultiplier=2 , CompletedByUserId=2,CompletedButton = "" },
new ProjectTaskLineItemSummary(){TenantId = 3, Id =3, Name = "rollex ",Description= "rrrr",CostMultiplier=3 ,CompletedDate =DateTime.UtcNow, CompletedByUserId=3 ,CompletedButton = ""}
};
setButtonIsCompleted();
}
private void setButtonIsCompleted()
{
foreach (var task in Tasks)
{
if (task.CompletedDate == null)
{
task.CompletedButton = "Mark Task as Completed";
}
else
{
task.CompletedButton = "Mark Task as inCompleted";
}
}
}
}