Question

The problem I'm trying to solve is fairly straight forward, I'm using Microsoft.Phone.Controls and I'm trying to bind to two properties of ToggleSwitch in my MainPageViewModel so I can capture the state of the ToggleSwitch and change its content from 'on/off' to 'distance/time' for example.

What I'm doing doesn't work, it's something to do with conventions that I haven't quite figured out from the docs (RTFM...). This doesn't work:

using System;
using System.Windows.Data;
using System.Collections.Generic;
using Caliburn.Micro;
using Microsoft.Phone.Controls;

public class AppBootstrapper : PhoneBootstrapper
{
    PhoneContainer container;

    protected override void Configure()
    {
        container = new PhoneContainer(RootFrame);

        container.RegisterPhoneServices();
        container.PerRequest<MainPageViewModel>();

        AddCustomConventions();
    }

    private static void AddCustomConventions()
    {
        ConventionManager.AddElementConvention<ToggleSwitch>(ToggleSwitch.IsCheckedProperty, "IsChecked", "Click")
            .ApplyBinding = (viewModelType, path, property, element, convention) =>
            {
                //Default binding to "IsChecked" property
                if (!ConventionManager.SetBinding(viewModelType, path + ".IsChecked", property, element, convention))
                    return false;

                if (!ConventionManager.HasBinding(element, ToggleSwitch.ContentProperty))
                {
                    var binding = new Binding(path + ".Content");

                    BindingOperations.SetBinding(element, ToggleSwitch.ContentProperty, binding);
                }

                return true;
            };
    }
}

and

    bool fixedDistance = true;
    public bool FixedDistance
    {
        get
        {
            return fixedDistance;
        }
        set
        {
            fixedDistance = value;
            NotifyOfPropertyChange(() => FixedDistance);

            if (fixedDistance)
            {
                FixedDistanceContent = "Distance";
            }
            else
            {
                FixedDistanceContent = "Time";
            }
        }
    }

    string fixedDistanceContent;

    public string FixedDistanceContent
    {
        get
        {
            return fixedDistanceContent;
        }
        set
        {
            fixedDistanceContent = value;
            NotifyOfPropertyChange(() => FixedDistanceContent);
        }
    }

where the ToggleSwitch has the xaml Name=FixedDistance.

I'm naively (and clearly incorrectly) expecting the ToggleSwitch.IsChecked to be bound to the FixedDistance property, and the ToggleSwitch.Content to be bound to FixedDistanceContent.

Thanks!

Était-ce utile?

La solution

It looks like this:

        ConventionManager.AddElementConvention<ToggleSwitch>(
            ToggleSwitch.IsCheckedProperty,
            "IsChecked",
            "Click");
            .ApplyBinding = (viewModelType, path, property, element, convention) =>
        {
            if (!ConventionManager.SetBinding(viewModelType, path, property, element, convention))
                return false;

            if (ConventionManager.HasBinding(element, ToggleSwitch.ContentProperty)) return true;

            var binding = new Binding(path + "Content") { Mode = BindingMode.TwoWay };
            BindingOperations.SetBinding(element, ToggleSwitch.ContentProperty, binding);

            return true;
        };

does the trick.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top