为了账号安全,请及时绑定邮箱和手机立即绑定

XAML 单击时切换 ListViewItem 可见性

XAML 单击时切换 ListViewItem 可见性

C#
拉风的咖菲猫 2023-12-17 20:05:39
我正在尝试根据所选的 ListViewItem 更改项目可见性。基本上,ListView 中的每一列在网格上都有两个项目、一个标签和一个控件(组合框、日期选择器、文本框等)。如果选择 ListViewItem,那么我希望该行中的所有控件都可见,否则标签应该可见。这是在 UserControl 上,而不是在 Window 上,如果这有什么区别的话。这是我的视图模型    public class DailyServiceLogsViewModel{     public int DailyServiceLogID { get; set; }    public int EmployeePositionID { get; set; }    public PositionType SelectedEmployeePosition { get; set; }    public List<PositionType> EmployeePositionList { get; set; }    public List<EmployeeSelectionListViewModel> EmployeeList { get; set; }    public EmployeeSelectionListViewModel SelectedEmployee { get; set; }    public string EmployeeName { get; set; }    public string PositionDescription { get; set; }    public DateTime? Date { get; set; }    public string WorkArea { get; set; }    public bool SelectedLog { get; set; }}代码隐藏            private DBContext _dbContext= new DBContext();            public ObservableCollection<DailyServiceLogsViewModel> DailyServiceLogs { get; set; }            public void OnLoad()            {                _dbContext= new DBContext();                List<EmployeeSelectionListViewModel> employeeList = _dbContext.Employees.Where(emp => emp.Active).Select(employee => new EmployeeSelectionListViewModel { EmployeeID = employee.EmployeeID, EmployeeName = employee.FirstName + " " + employee.LastName }).ToList();                DailyServiceLogs = new ObservableCollection<DailyServiceLogsViewModel>();                foreach (var serviceLog in _dbContext.DailyServiceLogs.Where(d => d.PayPeriodID == CurrentPayPeriod.PayPeriodID).OrderBy(d =>                   }                  ListViewTest.DataContext = this;                  ListViewTest.ItemsSource = DailyServiceLogs;                }我尝试过使用 DataTriggers,但我对它们不太熟悉
查看完整描述

1 回答

?
侃侃尔雅

TA贡献1801条经验 获得超15个赞

保持 SelectedLog 更新的正确方法是为 ListView 创建一个 ItemContainerStyle 并将其绑定在那里。这是正确的解决方案。您需要使项目视图模型成为实现 INotifyPropertyChanged 的实际视图模型。事实上,更改该属性永远不会影响 UI 中的任何内容,因为 UI 不会收到更改通知。该解决方案如下。


但是,如果视图模型并不特别关心它是否被选中,我们可以删除您的 SelectionChanged 处理程序,从项目类中删除 SelectedLog,然后直接绑定到触发器中 ListViewItem 的实际 IsSelected 属性。请注意,您将组合框设置为在选择项目时可见,但在未选择项目时从未隐藏它。我已经解决了这个问题。当我们被选中时,一个控件会隐藏,而当我们未被选中时,另一个控件会隐藏。


<Label Content="{Binding EmployeeName}" >

    <Label.Style>

        <Style TargetType="{x:Type Label}">

            <Style.Triggers>

                <DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=ListViewItem}}" Value="True">

                    <Setter Property="Visibility" Value="Hidden"/>

                </DataTrigger>

            </Style.Triggers>

        </Style>

    </Label.Style>

</Label>

<ComboBox Tag="{Binding ElementName=gdEmployee, Path=Tag}" ItemsSource="{Binding EmployeeList}" SelectedValue="{Binding SelectedEmployee.EmployeeID}" DisplayMemberPath="EmployeeName" SelectedValuePath="EmployeeID" FlowDirection="LeftToRight" Margin="15,5" HorizontalAlignment="Stretch" >

    <ComboBox.Style>

        <Style TargetType="{x:Type ComboBox}">

            <Style.Triggers>

                <DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=ListViewItem}}" Value="False">

                    <Setter Property="Visibility" Value="Hidden"/>

                </DataTrigger>

            </Style.Triggers>

        </Style>

    </ComboBox.Style>

</ComboBox>

您应该学习如何创建和绑定视图模型属性,这就是该解决方案。首先,我们需要创建“viewmodel”实际的视图模型:


public class DailyServiceLogsViewModel : ViewModelBase

{

    public int DailyServiceLogID { get; set; }

    public int EmployeePositionID { get; set; }

    public PositionType SelectedEmployeePosition { get; set; }

    public List<PositionType> EmployeePositionList { get; set; }

    public List<EmployeeSelectionListViewModel> EmployeeList { get; set; }

    public EmployeeSelectionListViewModel SelectedEmployee { get; set; }

    public string EmployeeName { get; set; }

    public string PositionDescription { get; set; }

    public DateTime? Date { get; set; }

    public string WorkArea { get; set; }


    //  Only properties like this will notify the UI when they update. 

    private bool _isSelectedLog = false;

    public bool IsSelectedLog

    {

        get => _isSelectedLog;

        set => SetProperty(ref _isSelectedLog, value);

    }

}


public class ViewModelBase : INotifyPropertyChanged

{

    public event PropertyChangedEventHandler PropertyChanged;


    protected virtual void OnPropertyChanged([CallerMemberName] string propName = null) =>

        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));


    public void SetProperty<T>(ref T field, T value, [CallerMemberName] string propName = null)

    {

        if (!Object.Equals(field, value))

        {

            field = value;

            OnPropertyChanged(propName);

        }

    }

}

其次,添加一个 ItemContainerStyle,用于在选择项目时设置 IsSelectedLog。您可以删除 SelectionChanged 处理程序。


<ListView ItemsSource="{Binding Items}">

    <ListView.ItemContainerStyle>

        <Style TargetType="ListViewItem">

            <Setter Property="IsSelected" Value="{Binding IsSelectedLog}" />

        </Style>

    </ListView.ItemContainerStyle>

    <ListView.View>

        <GridView>

            <GridViewColumn x:Name="clmServiceEmployeeName" Header="Employee" Width="155">

                <GridViewColumn.CellTemplate>

                    <DataTemplate>

                        <Grid Tag="{Binding DailyServiceLogID}">

                            <Label Content="{Binding EmployeeName}" >

                                <Label.Style>

                                    <Style TargetType="{x:Type Label}">

                                        <Style.Triggers>

                                            <DataTrigger Binding="{Binding SelectedLog}" Value="True">

                                                <Setter Property="Visibility" Value="Hidden"/>

                                            </DataTrigger>

                                        </Style.Triggers>

                                    </Style>

                                </Label.Style>

                            </Label>

                            <ComboBox Tag="{Binding ElementName=gdEmployee, Path=Tag}" ItemsSource="{Binding EmployeeList}" SelectedValue="{Binding SelectedEmployee.EmployeeID}" DisplayMemberPath="EmployeeName" SelectedValuePath="EmployeeID" FlowDirection="LeftToRight" Margin="15,5" HorizontalAlignment="Stretch" >

                                <ComboBox.Style>

                                    <Style TargetType="{x:Type ComboBox}">

                                        <Style.Triggers>

                                            <DataTrigger Binding="{Binding SelectedLog}" Value="False">

                                                <Setter Property="Visibility" Value="Hidden"/>

                                            </DataTrigger>

                                        </Style.Triggers>

                                    </Style>

                                </ComboBox.Style>

                            </ComboBox>

                        </Grid>

                    </DataTemplate>

                </GridViewColumn.CellTemplate>

            </GridViewColumn>

        </GridView>

    </ListView.View>

</ListView>


查看完整回答
反对 回复 2023-12-17
  • 1 回答
  • 0 关注
  • 64 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信