В форме Xamarin для элементов представления коллекции, как установить кнопку на основе значения элемента? (условный бинфинг)

Я делаю проект формы Xamarin, у меня есть список задач, которые можно выполнить или завершить. Я хочу добавить кнопку для отображения «Отметить как завершенную» для завершенных задач и «Отметить как завершенную» для завершенных задач. конечно, он должен обновляться, когда пользователь щелкает один раз. У меня есть поле «CompletedDate», которое определяет, завершена ли задача, когда она имеет значение.

  TextColor = "{StaticResource PrimaryBlack}" />
                            <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 Orientation = "Horizontal">
                                                        <Label
                                                    FontFamily = "{StaticResource MeduimFont}"
                                                    Style = "{StaticResource LabelMedium}"
                                                    Text = "Completed"
                                                          IsVisible = "{Binding CompletedTaskVisibility}}"
                                                    TextColor = "{Binding PrimaryPersianGreen}" />
                                                        <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}" />
                                                    <Label
                                                Grid.Row = "3"
                                                Style = "{StaticResource LabelMedium}"
                                                Text = "{Binding Description}"
                                                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" />
                                                  
                                                </Grid>
                                            </Frame>
                                        </Grid>
                                    </DataTemplate>
                                </CollectionView.ItemTemplate>
                            </CollectionView>

У меня есть поле «CompletedDate», которое определяет, завершена ли задача, когда она имеет значение.

🤔 А знаете ли вы, что...
C# также используется для разработки игр с помощью Unity3D, популярного игрового движка.


59
2

Ответы:

Решено

Есть два решения:

  1. Создайте логическую переменную, которая проверяет CompletedDate в вашей модели представления и привязывает к ней текст. А затем используйте конвертер, чтобы преобразовать логическое значение в строку. Что касается события click, вы можете попробовать сделать то же самое, что и Text, или выполнить проверку события click в page.cs.
  2. Создайте логическую переменную и в модели представления, но вам нужно создать две кнопки (одна — «Пометить как выполненную», а другая — «Пометить как завершенную») в xaml и привязать их свойство IsVisible к логической переменной в просмотреть модель.

Я предлагаю вам попробовать второе решение, потому что первое нужно сделать много и преобразовать событие clicked в команду. И второй уменьшает много работы.

Наконец, вы можете попробовать использовать другие элементы управления вместо кнопки. Такие как:

Флажок:https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/checkbox

Переключатель:https://docs.microsoft.com/en-us/xamarin/xamarin-forms/пользовательский интерфейс/переключатель

Редактировать:

в модели представления:

 public ViewModel()
    {
        CompletedDate = ""; //set the value with the model data
        if (CompletedDate != null)
        {
            isCompleted = true;
        }
        else isCompleted = false;
 }

 public event PropertyChangedEventHandler PropertyChanged;

    bool isCompleted;
    public bool IsCompleted { 
        get { return isCompleted; } 
        set { 
              isCompleted = value;
              if (PropertyChanged != null)
              {
                  PropertyChanged(this, new PropertyChangedEventArgs("IsCompleted"));
              }
            }
    }

в xaml:

 <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" 
                                            IsVisible = "{Binding IsCompleted}"/>

 <Button
                                            x:Name = "lstbtnMarkasComplite"
                                            Grid.Row = "5"
                                            Padding = "15,0"
                                            Clicked = "MarkTaskAsInCompletedClicked"
                                            CornerRadius = "20"
                                            FontSize = "{StaticResource Font12}"
                                            HeightRequest = "40"
                                                     CommandParameter = "{Binding Id}"
                                            HorizontalOptions = "CenterAndExpand"
                                            Style = "{StaticResource ButtonPurple}"
                                            Text = "Mark as in Completed" 
                                            IsVisible = "{Binding IsCompleted}/>

Вы также можете использовать DataTrigger, как сказал Ibrennan208, а затем проверить значение Text в page.cs:

     private async void Button_Clicked(object sender, EventArgs e) 
     {
        Button button = sender as Button;
        if (button.Text == "Mark as Completed")
        {
            .........
        }
        else
        {
            .........
        }
     }

Обновлять:

<Button.Triggers>
     <DataTrigger TargetType = "Button" Binding = "{Binding CompletedDate}" Value = "{x:Null}">
        <Setter Property = "Text" Value = "Mark Task as Completed"/>
     </DataTrigger>
</Button.Triggers>

Вы можете попробовать добавить DataTrigger в свой Button. Их можно использовать для применения условных привязок или значений к таким свойствам, как свойство Button.Text.

Для кнопки вы можете реализовать ее аналогично следующему:

    <Button Test = "Mark Complete">
        <Button.Triggers>
            <DataTrigger TargetType = "Button" Binding = "{Binding IsCompleted}" Value = "True">
                <Setter Property = "Text" Value = "Mark Incomplete"/>
            </DataTrigger>
        </Button.Triggers>
    </Button>

Затем вы также можете добавить поле IsCompleted в свою модель представления:

public bool IsCompleted             
            get { return CompletedDate.HasValue; }
        

который будет действовать как переключатель для вашей кнопки.

Вам также необходимо добавить уведомление для переменной IsCompleted.

Вызов OnPropertyChanged(nameof(IsCompleted)) при установке CompletedDate сделает это.