gpt4 book ai didi

android - 如何在 Xamarin Forms 应用程序 (android) 中仅激活 1 个 ListView 项目并禁用其他项目

转载 作者:太空狗 更新时间:2023-10-29 13:44:19 26 4
gpt4 key购买 nike

具有如下所示的 ListView,其中包含代表 Tasks 及其各自 Status 的项目:

ListView

TasksPage XAML:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:iFacilityMob;assembly=iFacilityMob"
x:Class="iFacilityMob.TasksPage">
<ContentPage.Content>
...
<ListView
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
x:Name="TasksListView"
HasUnevenRows="True"
SeparatorVisibility="None"
SelectionMode="None"
IsPullToRefreshEnabled="True"
Refreshing="TasksListView_OnRefreshing"
CachingStrategy="RetainElement">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<local:TaskCardTemplate></local:TaskCardTemplate>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
...
</ContentPage.Content>

任务卡模板 XAML:

<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="iFacilityMob.TaskCardTemplate">
<ContentView.Content>
<Frame x:Name="Frame"
IsClippedToBounds="True"
HasShadow="True"
Padding="2,5,5,2"
BackgroundColor="White"
Margin="10"
CornerRadius="5">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>

<!-- Vertical colored bar on the left which indicates the current Status -->
<BoxView x:Name="BVInitial" Grid.Row="0" Color="Green" IsVisible="{Binding InitialStatus}" Grid.RowSpan="2" Grid.Column="0" WidthRequest="8" Margin="0" CornerRadius="3"/>
<BoxView x:Name="BVStarted" Grid.Row="0" Color="DarkOrange" IsVisible="{Binding Started}" Grid.RowSpan="2" Grid.Column="0" WidthRequest="8" Margin="0" CornerRadius="3"/>
<BoxView x:Name="BVPaused" Grid.Row="0" Color="DodgerBlue" IsVisible="{Binding Paused}" Grid.RowSpan="2" Grid.Column="0" WidthRequest="8" Margin="0" CornerRadius="3"/>
<BoxView x:Name="BVFinished" Grid.Row="0" Color="Black" IsVisible="{Binding Finished}" Grid.RowSpan="2" Grid.Column="0" WidthRequest="8" Margin="0" CornerRadius="3"/>

<!-- Button Start -->
<Button Grid.Row="0" Grid.Column="1" x:Name="BtnStartTask" Text="Start" TextColor="White" BackgroundColor="Green" CornerRadius="5" Margin="5,5,0,0" HeightRequest="40"
Clicked="BtnStartTask_OnClicked" IsEnabled="{Binding StartEnabledAndVisible}" IsVisible="{Binding StartEnabledAndVisible}" CommandParameter="{Binding .}" />

<!-- Button Pause -->
<Button Grid.Row="0" Grid.Column="1" x:Name="BtnPauseTask" Text="Pause" TextColor="White" BackgroundColor="DodgerBlue" CornerRadius="5" Margin="5,5,0,0" HeightRequest="40"
Clicked="BtnPauseTask_OnClicked" IsEnabled="{Binding PauseEnabled}" IsVisible="{Binding PauseVisible}" CommandParameter="{Binding . }" />

<!-- Button End -->
<Button Grid.Row="1" Grid.Column="1" x:Name="BtnEndTask" Text="End" TextColor="White" BackgroundColor="Red" CornerRadius="5" Margin="5,0,0,5" HeightRequest="40"
Clicked="BtnEndTask_OnClicked" IsEnabled="{Binding EndEnabled}" CommandParameter="{Binding .}" />

...
<!-- The data of each Task, not important in this case -->
</Grid>
</Frame>
</ContentView.Content>

通过单击按钮,我可以更改任何 Task 项目的状态和 View 。

private async void BtnStartTask_OnClicked(object sender, EventArgs e)
{
var btn = (Button)sender;
if (btn.CommandParameter is TaskViewModel model)
{
// Task
if (model.ModelType == Enums.ModelType.Task.ToString())
{
await _api.UpdateStatus(new StatusUpdateDTO
{ID = model.ID, ModelType = Enums.ModelType.Task.ToString(), StatusID = (int) Enums.TaskStatus.Started});
}
else// Ticket
{
await _api.UpdateStatus(new StatusUpdateDTO
{ ID = model.ID, ModelType = Enums.ModelType.Ticket.ToString(), StatusID = (int)Enums.TicketStatus.Assigned });
}

UpdateView(Enums.Buttons.Start);
}

private void UpdateView(Enums.Buttons buttonPressed)
{
switch (buttonPressed)
{
case Enums.Buttons.Start:
// Hide Start
BtnStartTask.IsEnabled = false;
BtnStartTask.IsVisible = false;

// Show Pause
BtnPauseTask.IsEnabled = true;
BtnPauseTask.IsVisible = true;

// Enable End
BtnEndTask.IsEnabled = true;
BtnEndTask.IsVisible = true;

BVStarted.IsVisible = true;
BVFinished.IsVisible = false;
BVInitial.IsVisible = false;
BVPaused.IsVisible = false;
break;

case Enums.Buttons.Pause:
...

case Enums.Buttons.End:

...
}
}

一旦 Task Started,我如何实现这一点,我以某种方式禁用(禁用覆盖和按钮)所有其他 Tasks 和最终在 Activity 任务 PausedEnded 时重新启用它们?

编辑:

任务页面 View 模型:

public class TaskViewModel: INotifyPropertyChanged
{
public int ID { get; set; }// TaskID or TicketID
public string ModelType { get; set; }// Task or Ticket
public string Title { get; set; }
public string Description { get; set; }
public int FloorID { get; set; }
public string FloorName { get; set; }
public int AreaID { get; set; }
public string AreaName { get; set; }
public int? ScheduledTaskID { get; set; }
public int? ScheduleID { get; set; }

private int _statusID { get; set; } // Task Status or TicketTask
public int StatusID
{
get => _statusID;
set
{
_statusID = value;
OnPropertyChanged();
}
}

public bool ActiveItem => (IsTask && (StatusID == (int) Enums.TaskStatus.Started )) || IsTicket && (StatusID == (int) Enums.TicketStatus.InProgress);

public bool NotActive => !ActiveItem;

public List<ProductDTO> Products { get; set; }

public bool IsTask => ModelType == ModelTypes.Task.ToString();
public bool IsTicket => ModelType == ModelTypes.Ticket.ToString();

public bool StartEnabledAndVisible
{
get
{
if (IsTask && StatusID == (int)Enums.TaskStatus.Created || StatusID == (int) Enums.TaskStatus.Paused)
{
return true;
}

return IsTicket && StatusID == (int) Enums.TicketStatus.Assigned;
}
}

public bool PauseEnabled
{
get
{
if (IsTask && StatusID == (int)Enums.TaskStatus.Started)
{
return true;
}

return IsTicket && StatusID == (int)Enums.TicketStatus.InProgress;
}
}

public bool PauseVisible
{
get
{
if (IsTask && StatusID == (int)Enums.TaskStatus.Started || StatusID == (int)Enums.TaskStatus.Finished)
{
return true;
}

return IsTicket && StatusID == (int)Enums.TicketStatus.InProgress || StatusID == (int)Enums.TicketStatus.Closed;
}
}

public bool EndEnabled
{
get
{
if (IsTask && StatusID == (int)Enums.TaskStatus.Started || StatusID == (int)Enums.TaskStatus.Paused)
{
return true;
}

return IsTicket && StatusID == (int)Enums.TicketStatus.InProgress || StatusID == (int)Enums.TicketStatus.Assigned;
}
}

public bool InitialStatus => IsTask && StatusID == (int) Enums.TaskStatus.Created || IsTicket && StatusID == (int)Enums.TicketStatus.Assigned;

public bool Started => IsTask && StatusID == (int)Enums.TaskStatus.Started || IsTicket && StatusID == (int)Enums.TicketStatus.InProgress;

public bool Paused => IsTask && StatusID == (int)Enums.TaskStatus.Paused || IsTicket && StatusID == (int)Enums.TicketStatus.Assigned;

public bool Finished => IsTask && StatusID == (int)Enums.TaskStatus.Finished || IsTicket && StatusID == (int)Enums.TicketStatus.Closed;

public string ProductsLabel
{
get
{
return Products != null ? string.Join(", ", Products.Select(p => p.Name)) : "";
}
}

public event PropertyChangedEventHandler PropertyChanged;

protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

而在 TasksPage 中,父页面:

protected override async void OnAppearing()
{
_scheduledTasks = new ObservableCollection<TaskViewModel>(_schedule.ScheduledTasks.OrderBy(st => st.Finished));
TasksListView.ItemsSource = _scheduledTasks;
}

任务页面模型:

public class ScheduleDTO
{
public int ScheduleID { get; set; }
public DateTime ScheduleDate { get; set; }
public int WorkerID { get; set; }
public bool OnHoliday { get; set; }
public DateTime StartDatetime { get; set; }
public DateTime StopDatetime { get; set; }
public DateTime CurrentDateTime { get; set; }
public DateTime? LoggedInTime { get; set; }
public DateTime? LoggedOutTime { get; set; }
public string LateReason { get; set; }
public string EarlyLogoutReason { get; set; }
public string LateLogoutReason { get; set; }

// This should be the source for the Listview
public List<TaskViewModel> ScheduledTasks { get; set; }
}

最佳答案

我会建议将所有 View 逻辑放在 View 模型中。它会引发一些重构,但会更加简洁和可扩展。这样做,您只需将委托(delegate)从 TaskPageViewModel 传递到所有 TaskViewModel,这将触发所有其他任务的激活:

public class TaskPageViewModel
{
IApi _api;

public TaskPageViewModel(IApi api)
{
_api = api;
}

List<TaskViewModel> Tasks;

public void CreateTasks()
{
Tasks.Add(new TaskViewModel(OnTaskStatusChanged));

...
}

private void OnTaskStatusChanged(TaskViewModel selectedViewModel)
{
if (selectedViewModel.ModelType == Enums.ModelType.Task.ToString())
{
await _api.UpdateStatus(new StatusUpdateDTO
{ID = selectedViewModel.ID, ModelType = Enums.ModelType.Task.ToString(), StatusID = (int)Enums.TaskStatus.Started});
}

var taskStatus = selectedViewModel.Status;
foreach (var task in Tasks)
{
if (selectedViewModel != task)
{
task.IsEnable = taskStatus == Status.Pause || taskStatus == Status.End;
}
}
}
}

public class TaskViewModel
{
private readonly Action<TaskViewModel> _onTaskStatusChanged;

public TaskViewModel(Action<TaskViewModel> onTaskStatusChanged)
{
_onTaskStatusChanged = onTaskStatusChanged;
}

public ICommand TaskStatusChangedCommand;

public bool IsEnable;

public void TaskStatusChanged()
{
_onTaskStatusChanged(this);
}
}

然后您只需将 StatusChangedCommand 和 IsEnable 属性绑定(bind)到您的按钮和框 View 。您将在父 View 模型中拥有所有业务逻辑(api 调用)。

关于android - 如何在 Xamarin Forms 应用程序 (android) 中仅激活 1 个 ListView 项目并禁用其他项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57256139/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com