I am doing a Xamarin form project, I have a list of tasks that can be completed or in completed. I want to add a button to display "Mark as completed" for in completed tasks and "Mark as in completed" for completed tasks. of course, it needs to refresh when the user clicks once. I have a "CompletedDate" field that defines whether the task is completed when it has value.
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>
I have a "CompletedDate" field that defines whether the task is completed when it has value.
CodePudding user response:
You could try adding a DataTrigger
to your Button
. They can be used to apply conditional bindings or values to properties such as the Button.Text
property.
For a button you could implement it similarly to the following:
<Button Test="Mark Complete">
<Button.Triggers>
<DataTrigger TargetType="Button" Binding="{Binding IsCompleted}" Value="True">
<Setter Property="Text" Value="Mark Incomplete"/>
</DataTrigger>
</Button.Triggers>
</Button>
And then you could also add the IsCompleted
field to your viewmodel:
public bool IsCompleted
get { return CompletedDate.HasValue; }
which would act as the switch for your button.
You would also need to add notification for the IsCompleted
variable.
Calling OnPropertyChanged(nameof(IsCompleted)
when you set CompletedDate
will do that.
CodePudding user response:
There are two solutions:
- Create a boolean variable which checks the CompletedDate in your viewmodel and binding the Text to it. And then use a converter to convert the bool to string. About the clicked event, you can try to do the same thing as the Text or do a check in the click event in the page.cs.
- Create a boolean variable in the view model too, but you need to create two button(one is "Mark as completed" and the other is "Mark as in completed") in the xaml and binding their IsVisible property to the boolean variable in the view model.
I suggest you to try the second solution, because the first one need to do a lot and convert the clicked event to a command. And the second one reduce much work.
Finally, you may try to use some other controls instead of the button. Such as:
CheckBox:https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/checkbox
Switch:https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/switch
Edit:
in the view model:
public event PropertyChangedEventHandler PropertyChanged;
bool isCompleted;
public bool IsCompleted {
get { return isCompleted; }
set {
isCompleted = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("IsCompleted"));
}
}
}
in the 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}/>
You can also use the DataTrigger just like Ibrennan208 sayed, and then check the Text value in the page.cs:
private async void Button_Clicked(object sender, EventArgs e)
{
Button button = sender as Button;
if(button.Text == "Mark as Completed")
{
.........
}
else
{
.........
}
}