如何在 C# UWP 的 ListView 中访问 ToggleSwitch 实例?
How to get access to ToggleSwitch instance within ListView in C# UWP?
我打开了问题 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;
}
}
}
但这只会让一个切换开关起作用。它是对应于最后添加到列表中的产品的开关(我猜它指的是最后一个 Id)。其他开关 return 没有,好像该方法没有正确遍历列表,或者好像只有一个开关连接。
那么,是否可以像我尝试做的那样只使用一个 Toggled 事件来启动所有开关并 运行?
这是一个展示一种方法的示例。
在此示例中,我们有以下产品视图模型:
public class Product : INotifyPropertyChanged
{
private string _name;
public string Name
{
get => _name;
set
{
if (value == _name) return;
_name = value;
OnPropertyChanged();
}
}
所以只有一个 Name-property。
然后我们有 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}";
}
所以在几次切换之后:
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。
它现在就像一个魅力。
我打开了问题 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;
}
}
}
但这只会让一个切换开关起作用。它是对应于最后添加到列表中的产品的开关(我猜它指的是最后一个 Id)。其他开关 return 没有,好像该方法没有正确遍历列表,或者好像只有一个开关连接。
那么,是否可以像我尝试做的那样只使用一个 Toggled 事件来启动所有开关并 运行?
这是一个展示一种方法的示例。
在此示例中,我们有以下产品视图模型:
public class Product : INotifyPropertyChanged
{
private string _name;
public string Name
{
get => _name;
set
{
if (value == _name) return;
_name = value;
OnPropertyChanged();
}
}
所以只有一个 Name-property。
然后我们有 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}";
}
所以在几次切换之后:
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。
它现在就像一个魅力。