在用户手动设置后以编程方式设置WPF GridView列宽

m4pnthwp  于 2023-02-25  发布在  其他
关注(0)|答案(1)|浏览(176)

我希望能够通过用户右键单击列标题来折叠/取消折叠ListViewGridColumn。下面是一个实现这一点的最小示例,但是一旦用户手动调整列大小(通过单击并拖动边距),它就会停止工作。为什么会这样?我该怎么做才能允许用户手动调整大小和我想要的折叠/取消折叠?
(It停止工作的意义上说,列不再响应右键单击)。在调试器中,我可以看到,在用户调整大小后,转换器不再被调用,所以可能是绑定到宽度消失了?为什么?)

MainWindow.xaml(为简洁起见,省略了标题)

<Window.DataContext>
        <local:MainWindowViewModel/>
    </Window.DataContext>
    <Window.Resources>       
        <local:ColVisToWidth x:Key="ColVisToWidth"/>
    </Window.Resources>
    <Grid>
        <ListView ItemsSource="{Binding ListItems}">
            <ListView.View>
                <GridView>
                    <GridViewColumn Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=DataContext.ColVisible, Converter={StaticResource ColVisToWidth}}">
                        <GridViewColumnHeader Content="MyHeader">
                            <i:Interaction.Triggers>
                                <i:EventTrigger EventName="MouseRightButtonUp">
                                    <i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=DataContext.ToggleColVis}"/>
                                </i:EventTrigger>
                            </i:Interaction.Triggers>
                        </GridViewColumnHeader>
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding}"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>

主窗口视图模型

public class MainWindowViewModel:INotifyPropertyChanged
    {
        public MainWindowViewModel()
        {
            ToggleColVis = new RelayCommand(() => { ColVisible = !ColVisible; });
            ColVisible = true;
        }
        public RelayCommand ToggleColVis { get; set; }
        private bool colVisible;
        public bool ColVisible
        {
            get { return colVisible; }
            set { colVisible = value; OnPropertyChanged("ColVisible"); }
        }
        public List<string> ListItems { get; set; } = new List<string>() { "First", "Second" };

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged([CallerMemberName] string name = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }
    }

转换器

public class ColVisToWidth : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if ((bool)value)
            {
                return 120;
            }
            else
            {
                return 15;
            }
        }
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
sqougxex

sqougxex1#

最初,ColumnWidth属性值设置为绑定表达式,目的是绑定源一更改,有效值也随之更改(ColVisible属性)。悬停时,只要用户调整UI大小,它就会强制ColumnWidth具有新值-某个固定数字,该值将覆盖初始绑定表达式。然后,当绑定源更改时,列不再意识到变化,因为绑定不再是活动的。MVVM很酷,但我担心GridView中的列大小调整不是很符合模式,因为没有合适的API来定制处理调整大小的方式。因此,我建议您重写触发器操作,以调用直接设置Column.Width的命令,而不是使用中间绑定属性。

相关问题