【问题标题】:How to get access to ToggleSwitch instance within ListView in C# UWP?如何在 C# UWP 的 ListView 中访问 ToggleSwitch 实例?
【发布时间】:2018-04-05 18:48:09
【问题描述】:

我打开了问题here,但我们无法解决我的问题。我决定创建新问题,因为我们做出了一些假设,而前一个问题并未涉及真正的问题(我们认为这是绑定的问题,但正如您将读到的那样不是)。

简而言之,我有一个 ListView,其中包含来自名为jointList 的列表中的数据。 该列表运行良好,并且包含所有必要的数据。 (我查过了)

在 ListView 的每一行上,我放置了一个 ToggleSwitch(在 xaml 中),然后我尝试对每个开关做一些事情。

每个开关应对应同一行的数据。

我创建了应该适用于所有切换开关的 Toggled 事件,如下所示:

private void ToggleSwitch_Toggled(object sender, RoutedEventArgs e)
    {

        foreach (var product in jointList)
        {

            if (product.IsOn == true)
            {
                ToggleTest.Text = product.ProductId.ToString(); // this is for testing only, later I would do something with the data retrieved
                ToggleTest.Visibility = Visibility.Visible;
            }
            else
            {
                ToggleTest.Visibility = Visibility.Collapsed;
            }

        }

    }

但这只会让一个 toggleSwitch 工作。它是对应于列表中最后添加的产品的开关(我猜它指的是最后一个 Id)。其他开关什么也不返回,好像该方法没有正确地遍历列表,或者好像只有一个开关连接。

那么,是否可以像我尝试的那样仅使用一个 Toggled 事件来启动并运行所有开关?

【问题讨论】:

    标签: c# listview uwp toggle toggleswitch


    【解决方案1】:

    这是一个显示一种方式的示例。

    在这个例子中,我们有以下产品视图模型:

    public class Product : INotifyPropertyChanged
    {
        private string _name;
    
        public string Name
        {
            get => _name;
            set
            {
                if (value == _name) return;
                _name = value;
                OnPropertyChanged();
            }
        }
    

    所以只有一个名称属性。

    然后我们在 MainPage 中创建产品集合:

        private void FrameworkElement_OnLoaded(object sender, RoutedEventArgs e)
        {
            var items = new ObservableCollection<Product>();
            for (int i = 0; i < 9; i++)
            {
                items.Add(new Product($"item {i}"));
            }
    
            this.Items.ItemsSource = items;
        }
    

    以及创建视图的 XAML:

        <ListView Loaded="FrameworkElement_OnLoaded" x:Name="Items">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition/>
                            <ColumnDefinition/>
                        </Grid.ColumnDefinitions>
    
                        <TextBlock x:Name="RowContent" Text="{Binding Name}"/>
                        <ToggleSwitch x:Name="Toggle" Grid.Column="1" Toggled="Toggle_OnToggled"/>
                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    

    结果:

    现在我们想在用户切换开关时更改文本。这是在 Toggle_OnToggled-event 处理程序中完成的:

        private void Toggle_OnToggled(object sender, RoutedEventArgs e)
        {
            var toggle = (ToggleSwitch) sender;
    
            var dataContext = ((Grid)toggle.Parent).DataContext;
            var dataItem = (Product) dataContext;
    
            dataItem.Name = $"Toggled {toggle.IsOn}";
        }
    

    所以在几次切换之后:

    【讨论】:

    • 你好米凯尔!非常感谢您的回答。我必须承认,您给出的大多数代码我之前已经正确合并了一个示例,除了一个:onToggled 事件。我不知道如何将每个 toggleSwitch 与相应的行及其数据链接起来。非常感谢。
    • 只有一个问题。我的开关似乎倒置了。当我打开它时,数据消失了,当我关闭它时,数据显示出来..我一定是搞砸了什么
    【解决方案2】:

    Mikael Koskinen 已经解答了我的问题。

    我的大部分代码都是正确的,并且与他的解决方案相同,除了最后一位是 OnToggled 事件处理程序。 这是工作和正确的处理程序:

    private void Toggle_OnToggled(object sender, RoutedEventArgs e)
        {
            var toggle = (ToggleSwitch)sender;
    
            var dataContext = ((Grid)toggle.Parent).DataContext;
            var dataItem = (ScheduleList)dataContext;
    
            ToggleTest.Text = dataItem.ProductId;
        }
    

    我以前版本的处理程序没有包含重要的部分,即 dataContext 和 dataItem。

    它现在就像一个魅力。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-01
      • 2018-09-13
      • 1970-01-01
      • 2011-08-09
      • 1970-01-01
      • 1970-01-01
      • 2019-10-02
      • 2011-09-16
      相关资源
      最近更新 更多