0

In my main page, i have a listview of all the items, and once user clicks on one of them, it will navigate to a detail page. In the detail page, i create a last button to jump to last item,

        <Button Content="Last" HorizontalAlignment="Center" >
            <Interactivity:Interaction.Behaviors>
                <Interactions:EventTriggerBehavior EventName="Click">
                    <Interactions:InvokeCommandAction Command="{x:Bind Path=ViewModel.LastCommand, Mode=OneWay}"/>
                </Interactions:EventTriggerBehavior>
            </Interactivity:Interaction.Behaviors>
        </Button>

and here is part of my viewmodel for the page

class DetailPageViewModel : ViewModelBase
{
    private MyItem item;
    public MyItem Item
    {
        get { return item; }
        set { SetProperty(ref item, value); }
    }

    public DetailPageViewModel()
    {
        LastCommand = new DelegateCommand(LastItemExecute, CanLastItemExecute);
        LastCommand.ObservesProperty(() => Item);
    }

    private DelegateCommand lastCommand;
    public DelegateCommand LastCommand
    {
        get { return lastCommand; }
        set { SetProperty(ref lastCommand, value); }
    }

    private bool CanLastItemExecute()
    {
        if (Item.Index!= 1)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    private void LastItemExecute()
    {
        Item= _context.Items.Single(p => p.Index== Item.Index- 1);
    }
}

Everything works fine here, except that if i click on the first item in the listview, or jump from second item, the last button will not be disabled, click on it won't do anything though. But i would like to disable the button if the detail page is showing the first item, any help plz?

Brian Ding
  • 304
  • 3
  • 8

1 Answers1

0

But i would like to disable the button if the detail page is showing the first item.

Your "Last Button" is in the DetailPage, I don't know how you bind data to controls in this DetaiPage, but if you are using Mater/Detail pattern, you can refer to the official Master/detail sample, in the ItemViewModel model, there is a property Item_ID. My suggestion is that you can also add a ID properity into your data model for ListView in the Master page, so can the ID be passed within the selected Item to detail page after navigation.

Then in the DetailPageViewModel, you can get this ID and bind to the Button's IsEnable property with Converter:

<Page.Resources>
    <local:ButtonEnableConverter x:Key="cvt" />
</Page.Resources>
...

<Button VerticalAlignment="Center" HorizontalAlignment="Center" Content="Last Item" Grid.Row="3"
        IsEnabled="{x:Bind Item.ID, Mode=OneWay, Converter={StaticResource cvt}}">
    <Interactivity:Interaction.Behaviors>
        <Core:EventTriggerBehavior EventName="Click">
            <Core:InvokeCommandAction Command="{Binding Path=LastCommand, Mode=OneWay}" />
        </Core:EventTriggerBehavior>
    </Interactivity:Interaction.Behaviors>
</Button>

The code of ButtonEnableConverter is like this:

public class ButtonEnableConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        var itemID = (int)value;
        if (itemID != 0)
            return true;
        return false;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

Update:

I didn't wrote a full sample to test it, but it should be something like this:

<Button Content="Last Item" Grid.Row="1" HorizontalAlignment="Center" >
    <Interactivity:Interaction.Behaviors>
        <Core:DataTriggerBehavior Binding="{Binding Item.ID, Mode=OneWay}" ComparisonCondition="NotEqual" Value="100">
            <Core:ChangePropertyAction PropertyName="IsEnabled" Value="True"/>
        </Core:DataTriggerBehavior>
        <Core:DataTriggerBehavior Binding="{Binding Item.ID, Mode=OneWay}" ComparisonCondition="Equal" Value="100">
            <Core:ChangePropertyAction PropertyName="IsEnabled" Value="False"/>
        </Core:DataTriggerBehavior>
        <Core:EventTriggerBehavior EventName="Click">
            <Core:InvokeCommandAction Command="{Binding Path=LastCommand, Mode=OneWay}" />
        </Core:EventTriggerBehavior>
    </Interactivity:Interaction.Behaviors>
</Button>

You can have a try.

Grace Feng
  • 16,564
  • 2
  • 22
  • 45
  • Thank you for your reply and the code you provided. So first, my model indeed has a property "Index" (works as ID), if you could take a look at the method CanLastItemExecute, and command binding should automatically disable the button, when this method returns false, but it did not. Of course, your code is one way to work around, but i'd like a solution based on command binding. – Brian Ding Jul 26 '16 at 09:17
  • @BrianDing,but I thought your button command is for jumping to last item, and command can be fired only when your Button is clicked, but you want your Button to be disabled on the first item...I can't imagine that... – Grace Feng Jul 26 '16 at 11:44
  • By "last item", I mean the item with index less than that of current item, for example, when it is showing item with index=2, clicking on last button changes the viewmodel to first item(index=1) and disable the button, because there is no item has index=0. – Brian Ding Jul 27 '16 at 12:43
  • @BrianDing, OK, I just updated my answer, could you please take a try? – Grace Feng Jul 27 '16 at 13:17
  • yep, that works, but just like i said, i would like to disable the button automatically, through command, i understand that there are many other way around to disable the button, i just want to figure out why it does not work with command – Brian Ding Aug 03 '16 at 00:18