在ListView中添加来自DataTemplate的滑动条值
本文关键字:DataTemplate ListView 添加 | 更新日期: 2023-09-27 18:13:41
我创建了一个DataTemplate,它包含:一个TextBlock和一个Slider (x:Name="_score")。TextBlock引用了一个新的ObservableCollection,其中Category类包含一个字符串,它是TextBlock的文本。有7个项目的ListView使用了DataTemplate,所以在窗口中有7个滑块。
每次我改变滑块_score的值,我想用所有滑块值的总和更新一个TextBlock。不同的滑块会有不同的用户选择的值。我有一个ValueChanged="_slidScore "的事件处理程序。"
我是否可以区分滑块以添加每个滑块的总价值?
<Page.Resources>
<!-- TODO: Delete this line if the key AppName is declared in App.xaml -->
<x:String x:Key="AppName">Questionnaire</x:String>
<DataTemplate x:Key="_itemTemplate">
<Border BorderBrush="Gainsboro" BorderThickness="4">
<StackPanel Orientation="Horizontal">
<TextBlock Margin="8,0,8,0" FontSize="18" Width="200" VerticalAlignment="Center" TextWrapping="Wrap" Text="{Binding crit}"/>
<StackPanel>
<Slider Margin="10,0,10,0" VerticalAlignment="Center" Value="0" Maximum="5" Minimum="0" TickFrequency="1" TickPlacement="Outside" x:Name="_score" Width="641" ValueChanged="_slidScore"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<TextBlock VerticalAlignment="Center" Text="Rating: " FontSize="24"/>
<TextBlock VerticalAlignment="Center" Margin="10,0,0,0" Text="{Binding Value, ElementName=_score}" FontSize="24"/>
</StackPanel>
</StackPanel>
</StackPanel>
</Border>
</DataTemplate>
</Page.Resources>
....
in the main grid:
<Border Grid.Row="1" BorderBrush="Red" BorderThickness="5">
<TextBlock Text="how often have you..." TextWrapping="Wrap" FontWeight="Bold" FontSize="20" VerticalAlignment="Center"/>
</Border>
<ListView x:Name="_listView" Grid.Row="2" ItemTemplate="{StaticResource _itemTemplate}" SelectionMode="None" HorizontalContentAlignment="Stretch"/>
<TextBlock Grid.Row="2" Grid.Column="1" x:Name="_result" FontSize="70"/>
...
in codebehind file
//list to populate the TextBlock in DataTemplate
_listView.ItemsSource = new ObservableCollection<Category>
{
new Category{crit = "1231231231231231231?"},
new Category{crit = "asdfafhadgfjargfjagj?"},
new Category{crit = "qerklhjyahkildfjkladnhjkla?"},
new Category{crit = "13490p76812390-qhjsedhjklg?"},
new Category{crit = "asdfasdgq3e45uq345u?"},
new Category{crit = "q3490u8yq38945yasdjiofhj?"},
new Category{crit = "13406923789045whjioerghjkla?"}
};
class Category
{
public string crit { get; set; }
}
我找到了自己的答案:
int total = 0;
private void _slidScore(object sender, RangeBaseValueChangedEventArgs e)
{
total -= (int)e.OldValue;
total += (int)e.NewValue;
_result.Text = total.ToString();
}
_slidScore是滑动条的事件处理程序。然后将int total输出到TextBlock _result。
我会将滑块值存储在Category
类中:
private int _value;
public int value
{
get { return _value; }
set
{
if (value == _value) return;
_value = value;
OnPropertyChanged();
}
}
我将计算逻辑放在ViewModel
类中:
private int _totalValue;
public int TotalValue
{
get { return _totalValue; }
private set
{
if (value == _totalValue) return;
_totalValue = value;
OnPropertyChanged();
}
}
private ObservableCollection<Category> _categories;
public ObservableCollection<Category> Categories
{
get { return _categories; }
set
{
if (Equals(value, _categories)) return;
DetachHandlers(_categories); // not necessary if collection won't change after constructing ViewModel
_categories = value;
AttachHandlers(_categories); // could be only in constructor if collection won't cahnge later
OnPropertyChanged();
}
}
private void DetachHandlers(ObservableCollection<Category> categories)
{
// releases existing handlers
if (categories == null)
{
return;
}
foreach (var category in categories)
{
category.PropertyChanged -= CategoryOnPropertyChanged;
}
categories.CollectionChanged -= CategoriesOnCollectionChanged;
}
private void AttachHandlers(ObservableCollection<Category> categories)
{
if (categories == null)
{
return;
}
foreach (var category in categories)
{
// crucial: triggers when slider values change
category.PropertyChanged += CategoryOnPropertyChanged;
}
// necessary only if categories in the collection change later
categories.CollectionChanged += CategoriesOnCollectionChanged;
}
private void CategoriesOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs)
{
// detach handlers from removed categories
foreach (Category category in notifyCollectionChangedEventArgs.OldItems)
{
category.PropertyChanged -= CategoryOnPropertyChanged;
}
// attach handlers to added categories
foreach (Category category in notifyCollectionChangedEventArgs.NewItems)
{
category.PropertyChanged += CategoryOnPropertyChanged;
}
}
private void CategoryOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
{
if (propertyChangedEventArgs.PropertyName == "value")
{
// slider value changed: recalculate
TotalValue = Categories.Sum(c => c.value);
}
}
基本上,上面的代码附加了一个事件处理程序,该事件处理程序在每次类别值更改时触发并重新计算总数。
您需要向现有的XAML添加一些绑定:
<Slider x:Name="_score" Value="{Binding value, Mode=TwoWay}" />
<ListView x:Name="_listView" ItemsSource="{Binding Categories}" />
<TextBlock x:Name="_result" Text="{Binding TotalValue}" />
当然,在代码后面设置ViewModel
为DataContext
:
DataContext = new ViewModel
{
Categories = new ObservableCollection<Category>
{
new Category {crit = "1231231231231231231?"},
new Category {crit = "asdfafhadgfjargfjagj?"},
new Category {crit = "qerklhjyahkildfjkladnhjkla?"},
new Category {crit = "13490p76812390-qhjsedhjklg?"},
new Category {crit = "asdfasdgq3e45uq345u?"},
new Category {crit = "q3490u8yq38945yasdjiofhj?"},
new Category {crit = "13406923789045whjioerghjkla?"}
}
};