Как привязать переменную модели представления к элементам ObservableCollection в форме xamarin?

У меня есть список задач, которые мне нужны для привязки логической переменной к ее элементу. объект задачи включает свойство CompleteDate, которое, если оно имеет значение, определяет задачу как завершенную. в представлении мне нужно проверить, имеет ли значение текст кнопки, отображающий текст: «отметить как неполный»

----Объект задачи-----

   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);

            });
        }

вы устанавливаете личное isCompleted поле, а не общедоступное IsCompleted свойство

Jason 11.05.2022 15:10

Кроме того, на вашей виртуальной машине есть только одно свойство IsCompleted для нескольких объектов Task. Разве у каждого Task не должна быть своя IsCompleted собственность?

Jason 11.05.2022 15:23

Итак, каково решение?

Mah 12.05.2022 02:23

Вы не ответили на вопрос, который я задал. Для меня ваша виртуальная машина не имеет никакого смысла, но может быть причина делать это таким образом, которую вы не объяснили.

Jason 12.05.2022 02:38

ой, извини. Объект Task имеет поле «CompletedDate», которое определяет текст кнопки. если это имеет значение, моя кнопка должна быть «отметить как незавершенную», в противном случае должна быть «отметить как завершенную». так что, если я хочу использовать триггеры, как я могу с этим справиться? потому что у меня есть несколько задач на xaml с тем же полем, что и «CompletedDate». Я имею в виду, нужно ли мне несколько iscompleted? как?

Mah 12.05.2022 02:57
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
58
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Этого можно было бы просто добиться с помощью свойства BindingText кнопки, а затем динамически установить Text кнопки на основе CompletedDate объекта. Ниже приведены фрагменты кода для справки:

Модель: 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";
                }
            }
        }
    }

Другие вопросы по теме