Multiple ToggleSwitch instances get same data from

2019-08-18 02:31发布

问题:

This is my first experience with ToggleSwitch. What I am trying to achieve is to show different data from the list using different ToggleSwitches.

I have a ListView with multiple TextBlocks and one ToggleSwitch for each row of data.

Then I populate ListView with data from List. (List is populated using class that forsees

public ToggleSwitch Switch {get; set;}

Here is how I try to get ToggleSwitch data from each row:

private void ToggleSwitch_Toggled(object sender, RoutedEventArgs e)
    {

        for (int a = 0; a < jointList.Count; a++)
        {
               jointList[a].Switch = sender as ToggleSwitch;
            if (jointList[a].Switch != null)
            {
                if (jointList[a].Switch.IsOn == true)
                {
                    ToggleTest.Text = jointList[a].ProductId.ToString();

                    ToggleTest.Visibility = Visibility.Visible;


                }
                else
                {

                    ToggleTest.Visibility = Visibility.Collapsed;
                }
            }
        }



    }

Unfortunately I am getting the same(last added) productId from all of the ToggleSwitches as if they were pointing to same place.

EDIT> I have rewritten the code as touseef suggested:

private void ToggleSwitch_Toggled(object sender, RoutedEventArgs e)
    {

        for (int i = 0; i < jointList.Count; i++)
        {


                if (jointList[i].Value == true)
                {
                    ToggleTest.Text = jointList[i].ProductId.ToString();

                   // ToggleTest.Text = jointList[a].ProductId.ToString();
                    ToggleTest.Visibility = Visibility.Visible;


                }
                else
                {

                    ToggleTest.Visibility = Visibility.Collapsed;
                }

        }



    }

But now nothing shows up.

EDIT: Here is another attempt to resolve the problem:

private void ToggleSwitch_Toggled(object sender, RoutedEventArgs e)
    {

        foreach (var record in jointList)
        {

            if (record.Value == true)
            {
                ToggleTest.Text = record.ProductId.ToString();


                ToggleTest.Visibility = Visibility.Visible;


            }
            else
                {

                    ToggleTest.Visibility = Visibility.Collapsed;
                }

        }



    }

And now only one ToggleSwitch works, the one that corresponds to the last added record (I was pulling ProductId of the jointList). None of the other ToggleSwitches work. They don't return any data when using the code above.

回答1:

Please use DataTemplate to populate a listview and within your datatemplate put a toggleswitch, and x:Bind the IsOn value for your toggleswitch with a bool property within your item's class. and to get the correct values in your c# object behind set two way databinding.

basic databinding : https://docs.microsoft.com/en-us/windows/uwp/data-binding/data-binding-quickstart

binding in depth : https://docs.microsoft.com/en-us/windows/uwp/data-binding/data-binding-in-depth

you can bind with Binding or x:Bind the better way to bind in uwp is x:Bind though, see the links I provided you they will help you a lot :)

Instead of looping the list and getting sender as ToggleSwitch which will obviously give u same instance everytime. you should just loop over the list which you bind to the ListView, and then check your item.IsOn property and get ur item.ProductId and do whateer u want to with ur item object. note that this item came from the List of items which u are binding to the ListView. when u set two way databinding with toggleswitch, your item.IsOn property will automatically change when toggleswitch.IsOn changes, so you don't need to get any instance of toggleswitch in ur code.

INotify

in order to get notified about the propertychange and for two way databinding to work properly, you need to inherit your Product class from following class

public class Observable : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void Set<T>(ref T storage, T value, [CallerMemberName]string propertyName = null)
    {
        if (Equals(storage, value))
        {
            return;
        }

        storage = value;
        OnPropertyChanged(propertyName);
    }

    protected void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

and then in your IsOn property setter method, call onpropertychanged event like this.

 public class Product : Observable
{
    public int ProductId { get; set; }
    private bool isOn;

    public bool IsOn
    {
        get { return isOn; }
        set { isOn = value; Set(ref isOn, value, nameof(IsOn)); }
    }

}

Toggled Event

private void ToggleSwitch_Toggled(object sender, RoutedEventArgs e)
{
    //assuming productList is a List<Product> which was set as ListView.ItemSource
    foreach (var product in productList)
    {

        if (product.IsOn == true)
        {
            ToggleTest.Text = product.ProductId.ToString();
            ToggleTest.Visibility = Visibility.Visible;
        }
        else
        {
            ToggleTest.Visibility = Visibility.Collapsed;
        }

    }
}

if your problem still isn't solved, I will recommend you to put a simplistic app with this problem on the GitHub repo and share the link in your question so people can have a detailed look at it.