简体   繁体   中英

WP8 - Binding commands to buttons and switches in list

I am using MVVM pattern and I have LongListSelector in my page but I am not sure how to do these bindings:

  • I want in each row a button which do something with object in that row. I have this prepare in ViewModel:

     private RelayCommand<Module> goToTrackingPageCommand; public RelayCommand<Module> GoToTrackingPageCommand { get { return goToTrackingPageCommand ?? (goToTrackingPageCommand = new RelayCommand<Module>( NavigateToTrackingPage)); } } private void NavigateToTrackingPage(Module module) { App.Current.SelectedModule = module; navigationService.NavigateTo(new Uri("/Views/ModuleTrackingPage.xaml"), UriKind.Relative); } 

    And I am trying to bind it like this:

     <Button x:Name="ShowButton" Content="Show" Command="{Binding GoToTrackingPageCommand}" CommandParameter="{Binding}"/> 

    It's not working because button is in datatemplate and when there is binding it goes to selected Module object but not to ViewModel. So my first question is how can I fix it?

  • Second one is little complicated I guess but hope both get easy solution. I want have in each row ToggleSwitch too and when value is changed I want to call http request. I have this in datatemplate:

     <toolkit:ToggleSwitch x:Name="LockSwitch" IsChecked="{Binding IsLock}" /> 

    I could change binding to TwoWay but I change value in object and I want to call method in ViewModel with Module argument. So have can I change this binding? Should I someway call method in ViewModel from my object? Or should I somehow tell ViewModel that this object has changed this value? Or should I bind Checked and Unchecked event?

Regarding the Buttons: You can access the "parent datacontext" with an elementName binding and set the command parameter:

<Button Command="{Binding DataContext.GoToXyCommand, ElementName=LayoutRoot}" CommandParameter="{Binding}" />

Regarding your second question:

First, I would check if a toggle-button is the right solution, if changing the value triggers a process with a possibly longer duration.

An example where WP does this is enabling/disabling Air-Plane Mode.

I would do it the same way:

  • Bind to the property via TwoWayBinding
  • When the property is changed, start the updating process, disable the toggle button and show a progress indicator.

EDIT: Here is and example from a ViewModel I recently used.

    public bool IsUpdatingPushEnabled
    {
        get { return _isUpdatingPushEnabled; }
        set { SetProperty(ref _isUpdatingPushEnabled, value); }
    }

    public bool IsPushEnabled
    {
        get { return _isPushEnabled; }
        set
        {
            if (!IsUpdatingPushEnabled)
            {
                SetProperty(ref _isPushEnabled, value);
                var t = SetPushAsync();
            }
        }
    }

    private async Task SetPushAsync()
    {
        IsUpdatingPushEnabled = true;

        try
        {
            var result = await _settingService.EnablePushAsync(IsPushEnabled);
            SetProperty(ref _isPushEnabled, result, "IsPushEnabled");
        }
        catch
        {
            //...
        }

        IsUpdatingPushEnabled = false;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM