View IsEnabled Property is not working on Xamarin Forms
Here is my Listview Inside Listview button IsEnabled Property not working,IsEnabled False not working. I followed This step but still its not working https://forums.xamarin.com/discussion/47857/setting-buttons-isenabled-to-false-does-not-disable-button Inside My ViewModel
OrderItems=PopuldateOrders();// getting List Items
<ListView x:Name="OrderItems" VerticalOptions="Fill"
BackgroundColor="White" HasUnevenRows="True"
SeparatorVisibility="None" ItemsSource="{Binding OrderItems}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ContentView BackgroundColor="White">
<Grid BackgroundColor="Transparent" Margin="0" VerticalOptions="FillAndExpand" x:Name="Item">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10*"/>
<ColumnDefinition Width="18*"/>
<ColumnDefinition Width="18*"/>
<ColumnDefinition Width="17*"/>
<ColumnDefinition Width="20*"/>
<ColumnDefinition Width="17*"/>
</Grid.ColumnDefinitions>
<Label Text="{Binding PullSheetId}" Grid.Row="0" IsVisible="False"/>
<controls:CheckBox Checked="{Binding IsChecked}" Grid.Row="0" Grid.Column="0" IsVisible="{Binding IsEnableShipBtn}" Scale=".8"/>
<Label Text="{Binding KitSKU}" Grid.Row="0" Grid.Column="1"
HorizontalTextAlignment="Center" VerticalOptions="Center" FontSize="Small" TextColor="Black"/>
<Label Text="{Binding SKU}" Grid.Row="0" Grid.Column="2"
HorizontalTextAlignment="Center" VerticalOptions="Center" FontSize="Small" TextColor="{Binding ItemColor}"/>
<Label Text="{Binding ReqPackQty}" Grid.Row="0" Grid.Column="3"
HorizontalTextAlignment="Center" VerticalOptions="Center" FontSize="Small" TextColor="Black"/>
<local:EntryStyle Scale=".6" Text="{Binding ScanQuantity}" Grid.Row="0" Keyboard="Numeric"
Grid.Column="4" HorizontalTextAlignment="Center"
VerticalOptions="Center" Placeholder="Qty" IsEnabled="True" x:Name="QtyEntry"
>
<local:EntryStyle.Behaviors>
<eventToCommand:EventToCommandBehavior EventName="TextChanged"
Command="{Binding Source={x:Reference OrderItems}, Path=BindingContext.ChangeItemQty}"
CommandParameter="{Binding Source={x:Reference Item}, Path=BindingContext}"
/>
</local:EntryStyle.Behaviors>
</local:EntryStyle>
<Button Text="Ship" Scale=".6" Grid.Row="0" Grid.Column="5"
VerticalOptions="Center" BackgroundColor="#6eb43a" TextColor="White"
BorderRadius="20" CornerRadius="20" BorderColor="{Binding isError}" BorderWidth="3"
MinimumWidthRequest="60"
x:Name="ShipBtn"
Command="{Binding Source={x:Reference OrderItems}, Path=BindingContext.SubmitSingleItem}"
IsEnabled="{Binding IsEnableShipBtn}" IsVisible="{Binding IsEnableShipBtn}"
CommandParameter="{Binding .}"
/>
</Grid>
</ContentView>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.Behaviors>
<eventToCommand:EventToCommandBehavior EventName="ItemTapped" Command="{Binding PackerItemsItemTapped}"/>
</ListView.Behaviors>
</ListView>
How to solve this?
Solution 1:
You could achieve CanExecute
method in ICommand
to replace the IsEnabled property of Button. You could refer to my demo.
This is a GIF of my demo.
Firstly, You could see MainPage.xaml. Binding the model view and set command for Buttons.
<?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:TestDemo"
x:Class="TestDemo.MainPage">
<!--BindingContext from ButtonExecuteViewModel -->
<StackLayout>
<StackLayout.BindingContext>
<local:ButtonExecuteViewModel/>
</StackLayout.BindingContext>
<Button
Text="click me to enable following button"
Command="{Binding NewCommand}"/>
<Button
Text="Cancel"
Command="{Binding CancelCommand}"/>
</StackLayout>
Here is View Model ButtonExecuteViewModel.cs. You could see the construction method of ButtonExecuteViewModel
, it set the execute
and canExecute
to acheve isEnable of Button.
public class ButtonExecuteViewModel : INotifyPropertyChanged
{
bool isEditing;
public event PropertyChangedEventHandler PropertyChanged;
public ButtonExecuteViewModel()
{
NewCommand = new Command(
execute: () =>
{
IsEditing = true;
RefreshCanExecutes();
},
canExecute: () =>
{
return !IsEditing;
});
CancelCommand = new Command(
execute: () =>
{
IsEditing = false;
RefreshCanExecutes();
},
canExecute: () =>
{
return IsEditing;
});
}
void RefreshCanExecutes()
{
(NewCommand as Command).ChangeCanExecute();
(CancelCommand as Command).ChangeCanExecute();
}
public ICommand NewCommand { private set; get; }
public ICommand CancelCommand { private set; get; }
public bool IsEditing
{
private set { SetProperty(ref isEditing, value); }
get { return isEditing; }
}
//Determine if it can be executed
bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (Object.Equals(storage, value))
return false;
storage = value;
OnPropertyChanged(propertyName);
return true;
}
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}