上下文菜单的RelativeSource停止了DataTrigger的工作。

问题描述 投票:1回答:1

第一次发帖,长期阅读,也是wpf的新手,所以请对我温柔点:-)

我想用ListView创建一个用户列表,我在CollectionView中用红色的离线用户进行分组。有一个上下文菜单,只有在点击用户名称时才会显示。

对于上下文菜单的代码,我从另一个帖子中得到的,在这里 只适用于ListViewItem的ContextMenu。

我的问题是,只要我一添加上下文菜单,就不再触发颜色变化,所以我认为我是在不了解它们的工作原理的情况下,混合了这些方法。

<Grid>
             <ListView x:Name="lvUsers" ItemsSource="{Binding items}">
                <ListView.View>
                 <GridView>
                    <GridViewColumn> 
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <Image Source="{Binding Icon}"/>
                                 <TextBlock Margin="10,0,0,0" Text="{Binding UserName}"/>

                            </StackPanel>
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView>
                 </ListView.View>

            <ListView.Resources>
               <ContextMenu x:Key="ItemContextMenu">
               <MenuItem Header="More Info" Click="MenuItemDelete_Click" Command="{Binding Path=DataContext.MoreInfo, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}}" Background="WhiteSmoke" />
                </ContextMenu>

                <Style TargetType="{x:Type ListViewItem}">
                    <Setter Property="Foreground" Value = "Red"/>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Status}" Value ="Online">
                         <Setter Property="Foreground" Value="Black" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>

            </ListView.Resources>

            <ListView.ItemContainerStyle>
                <Style TargetType="{x:Type ListViewItem}" >
                    <Setter Property="ContextMenu" Value="{StaticResource ItemContextMenu}" />
                </Style>
            </ListView.ItemContainerStyle>

            <ListView.GroupStyle>
                <GroupStyle>
                    <GroupStyle.HeaderTemplate>
                        <DataTemplate>
                            <TextBlock FontWeight="Bold" FontSize="14"  Foreground="Black"  HorizontalAlignment="Center" Text="{Binding Name}"/>
                        </DataTemplate>
                    </GroupStyle.HeaderTemplate>
                </GroupStyle>
            </ListView.GroupStyle>

            </ListView>
        </Grid>

应该是什么样子的][1]。

![1]: https:/i.stack.imgur.comyu0Rx.png。

        {
            InitializeComponent();
            List<User> items = new List<User>();

            items.Add(new User() { Icon = ".\images\\white.png", UserName = "Tim Black", MessageColor ="Black", Status = Status.Online });
            items.Add(new User() { Icon = ".\white.png", UserName = "Colin Black", MessageColor = "Black", Status = Status.Online });
            items.Add(new User() { Icon = ".\images\\white.png", UserName = "Fred in Red", MessageColor = "Red" , Status = Status.Offline });

            lvUsers.ItemsSource = items;

            CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(lvUsers.ItemsSource);
            PropertyGroupDescription groupDescription = new PropertyGroupDescription("Status");
            view.GroupDescriptions.Add(groupDescription);

        }

        private void MenuItemDelete_Click(object sender, RoutedEventArgs e)
        {

            Console.WriteLine("context Pressed as source" + e.Source.ToString());
        }
    }
    public enum Status { Online, Offline };

    public class User
    {
        public string Icon { get; set; }
        public string UserName { get; set; }
        public string MessageColor { get; set; }
        public Status Status { get; set; }
    }



wpf listview contextmenu
1个回答
0
投票

我得到了这个工作。

在你的项目中添加一个新类 StatusToForeGroundConverter.

public class StatusToForeGroundConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if(value is Status status)
        {
            return status == Status.Online ? "black" : "red";
        }

        //fallback
        return "black";
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

将转换器添加到你的XAML中。

<Window.Resources>
    <local:StatusToForeGroundConverter x:Key="StatusConverter"/>
</Window.Resources>

然后就像这样绑定到它。

<TextBlock Margin="10,0,0,0" Text="{Binding UserName}" Foreground="{Binding Status,Converter={StaticResource StatusConverter}}"/>

Full xaml:

<Grid>
        <ListView x:Name="lvUsers" ItemsSource="{Binding items}">
            <ListView.View>
                <GridView>
                    <GridViewColumn>
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Horizontal">
                                    <Image Source="{Binding Icon}"/>
                                    <TextBlock Margin="10,0,0,0" Text="{Binding UserName}" Foreground="{Binding Status,Converter={StaticResource StatusConverter}}"/>

                                </StackPanel>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView>
            </ListView.View>

            <ListView.Resources>
                <ContextMenu x:Key="ItemContextMenu">
                    <MenuItem Header="More Info" Click="MenuItemDelete_Click" Command="{Binding Path=DataContext.MoreInfo, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}}" Background="WhiteSmoke" />
                </ContextMenu>

            </ListView.Resources>

            <ListView.ItemContainerStyle>
                <Style TargetType="{x:Type ListViewItem}" >
                    <Setter Property="Foreground" Value="{Binding MessageColor}" />
                </Style>
            </ListView.ItemContainerStyle>

            <ListView.GroupStyle>
                <GroupStyle>
                    <GroupStyle.HeaderTemplate>
                        <DataTemplate>
                            <TextBlock FontWeight="Bold" FontSize="14"  Foreground="Black"  HorizontalAlignment="Center" Text="{Binding Name}"/>
                        </DataTemplate>
                    </GroupStyle.HeaderTemplate>
                </GroupStyle>
            </ListView.GroupStyle>

        </ListView>
    </Grid>

Result

© www.soinside.com 2019 - 2024. All rights reserved.