我正在使用C#/ XAML构建Windows应用商店应用。
我有一个简单的ListView绑定到ItemsSource。有一个DataTemplate定义了每个项目的结构,其中包含ContentControl和TextBlock。
我希望在选择项目时更改TextBlock的前景色。有谁知道我怎么能这样做?
<ListView Grid.Column="1"
ItemsSource="{Binding Categories}"
ItemContainerStyle="{StaticResource CategoryListViewItemStyle}"
Background="{StaticResource DeepRedBrush}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ContentControl Content="{Binding Id, Converter={StaticResource Cat2Icon}}" HorizontalAlignment="Left" VerticalAlignment="Center" Width="110" Foreground="#FF29BCD6"/>
<TextBlock x:Name="catName" HorizontalAlignment="Left" Margin="0" TextWrapping="Wrap" Text="{Binding Name}" Grid.Column="1" VerticalAlignment="Center" FontSize="18.667"
Foreground="White"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
目前它被设置为“白色”,所以我需要的是一些绑定表达式,它将根据列表视图中项目的选定状态更改Foreground属性。
答案 0 :(得分:2)
这就是你所要求的。
使用此XAML
<Grid x:Name="LayoutRoot" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ListView x:Name="MyListView" ItemsSource="{Binding Items}" SelectionMode="Single" SelectedItem="{Binding Selected, Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Height="100" Width="300">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Ellipse x:Name="ellipse">
<Ellipse.Fill>
<SolidColorBrush Color="{Binding Color}" />
</Ellipse.Fill>
</Ellipse>
<TextBlock Grid.Column="1" VerticalAlignment="Center" Margin="10" Text="{Binding Title}" Style="{StaticResource HeaderTextBlockStyle}" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
这个代码背后:
public class MyModel : BindableBase
{
string _Title = default(string);
public string Title { get { return _Title; } set { SetProperty(ref _Title, value); } }
Color _Color = Colors.White;
public Color Color { get { return _Color; } set { SetProperty(ref _Color, value); } }
}
public class MyViewModel : BindableBase
{
public MyViewModel()
{
var items = Enumerable.Range(1, 10)
.Select(x => new MyModel { Title = "Title " + x.ToString() });
foreach (var item in items)
this.Items.Add(item);
}
MyModel _Selected = default(MyModel);
public MyModel Selected
{
get { return _Selected; }
set
{
if (this.Selected != null)
this.Selected.Color = Colors.White;
SetProperty(ref _Selected, value);
value.Color = Colors.Red;
}
}
ObservableCollection<MyModel> _Items = new ObservableCollection<MyModel>();
public ObservableCollection<MyModel> Items { get { return _Items; } }
}
public abstract class BindableBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void SetProperty<T>(ref T storage, T value, [System.Runtime.CompilerServices.CallerMemberName] String propertyName = null)
{
if (!object.Equals(storage, value))
{
storage = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
protected void RaisePropertyChanged([System.Runtime.CompilerServices.CallerMemberName] String propertyName = null)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
它会为您更新数据模板。
我想说明这一点:通过ViewModel更新列表内容是最简单,最轻量级的方法。在这种情况下,我正在更新绑定到椭圆的颜色。但是,如果这是一组复杂的变化,我可能只会设置一个样式。另一个选项是隐藏和显示模板中的整个控件集。但是,您无法更改数据模板,因为在网格重新绘制之前不会重新渲染数据模板,而这不是您想要执行的操作。
就像更改Ellipse颜色一样,您可以像在问题中一样更改TextBlock Foreground。无论哪种方式,这都能以最优雅的方式为您提供所需的一切。
祝你好运!
答案 1 :(得分:1)
您可以简单地处理SelectionChanged
上的ListView
事件,并通过更改{{1}上的视图模型值来更改先前所选项目的Foreground
和新选择的项目绑定到SelectedItem
。
您还可以使用Foreground
中的TextBlock
+ ListView.ItemContainerGenerator.ContainerFromItem(ListView.SelectedItem)
找到VisualTreeHelper
并直接更改前景,但如果ListView
该技术存在问题虚拟化(默认情况下),因为如果您从所选项目向外滚动并返回 - 具有更改的Foreground
的项目视图可能会被回收并用于您馆藏中的其他项目。
另一种选择是将Foreground
绑定到父IsSelected
的{{1}}属性,您也可以通过多种方式执行该属性。例如,您可以将整个ListViewItem
放在DataTemplate
中,并将UserControl
绑定到该控件的Foreground
。问题是我认为Parent
不是依赖属性,我在Parent
上看不到ParentChanged
事件(FrameworkElement
的基类定义了UserControl
属性) ,所以走这条路可能很难。绑定这些的另一种方法是定义一个附加的依赖属性或行为,为你设置绑定,但这很复杂(虽然我已经创建了一个你可以使用Jerry Nixon's blog post)。
最后,您可以修改Parent
并更改ListView.ItemContainerStyle
值。如果可行 - 这将是理想的解决方案。
SelectedBackground