【问题标题】:WPF DataGrid Checkbox doesn't update sourceWPF DataGrid Checkbox 不更新源
【发布时间】:2021-08-27 16:30:05
【问题描述】:

我创建了一个使用 AutoGeneratedColumns 的 DataGrid。除了 Checkbox 列之外,一切都按预期工作。单击复选框时,不会更新数据源。似乎 DataGrid 需要在更新数据源之前失去焦点。有没有一种简单的方法可以解决这个问题,还是我需要手动生成列?

Xaml:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="25" />
        <RowDefinition Height="*" />
        <RowDefinition Height="5" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <DockPanel>
        <Menu DockPanel.Dock="Top">
            <MenuItem Header="_File">
                <MenuItem x:Name="moNewSystem" Header="_New System" Click="moNewSystem_Click" />
                <MenuItem x:Name="moSaveSystems" Header="_Save Systems" Click="moSaveSystems_Click" />
                <MenuItem x:Name="moLoadSystems" Header="_Load Systems" Click="moLoadSystems_Click" />
                <Separator />
                <MenuItem x:Name="moExit" Header="E_xit" Click="moExit_Click" />
            </MenuItem>
        </Menu>
    </DockPanel>

    <DataGrid x:Name="dgvSystems" Grid.Row="1" ItemsSource="{Binding AllSystems, Mode=TwoWay}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" AutoGeneratingColumn="dgvSystems_AutoGeneratingColumn" />
    <GridSplitter Grid.Row="2" VerticalAlignment="Stretch" />
    <ListBox x:Name="lstOutput" Grid.Row="3" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
    
</Grid>

查看模型:

public class ViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

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

    private ObservableCollection<Systems> allSystems = new ObservableCollection<Systems>();
    public ObservableCollection<Systems> AllSystems 
    { 
        get { return allSystems; }
        set { allSystems = value; OnPropertyChanged(); }
    }
}

public class Systems : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

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

        private MainWindow Parent;

        private string symbol;
        public string Symbol
        {
            get { return symbol; }
            set { symbol = value; OnPropertyChanged(); }
        }

        private bool isEnabled;
        public bool IsEnabled
        {
            get { return isEnabled; }
            set 
            { 
                isEnabled = value;
                OnPropertyChanged();

                if (isEnabled)
                    StartSystem();
                else StopSystem();
            }
        }

        private void StartSystem()
        {
            Parent.Log("Started");
        }

        private void StopSystem()
        {
            Parent.Log("Stopped");
        }

        public Systems(MainWindow parent)
        {
            Parent = parent;
        }
    }

窗口:

public partial class MainWindow : Window
    {
        public ViewModel viewModel = new ViewModel();

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            DataContext = viewModel;

            foreach (var column in dgvSystems.Columns)
                column.Width = new DataGridLength(1, DataGridLengthUnitType.Star);
        }

        private void moNewSystem_Click(object sender, RoutedEventArgs e)
        {
            NewSystem nsWindow = new NewSystem(this);
            bool? result = nsWindow.ShowDialog();
            switch(result)
            {
                case true:
                    // Add System to collection
                    viewModel.AllSystems.Add(nsWindow.ThisSystem);
                    nsWindow.Close();
                    break;
            }
        }

        private void moSaveSystems_Click(object sender, RoutedEventArgs e)
        {

        }

        private void moLoadSystems_Click(object sender, RoutedEventArgs e)
        {

        }

        private void moExit_Click(object sender, RoutedEventArgs e)
        {

        }

        public void Log(string message)
        {
            string text = string.Format("{0}: {1}", DateTime.Now, message);
            lstOutput.Items.Insert(0, text);
        }
    }

【问题讨论】:

  • 您还应该共享您的代码隐藏,以防您使用 MouseLeftButtonUp 执行的操作会干扰更新 DataGrid 的 CheckBox 列。
  • 已编辑以包含附加代码。
  • 我是盲人,还是代码隐藏中缺少方法“dgvSystems_MouseLeftButtonUp”?编译器不会抱怨 is 吗?
  • 简单说一下约定:你的类 Systems 实际上是一个系统。因此,将其命名为复数可能会产生误导。为避免与系统命名空间发生冲突,您可能会为您的类型找到更好的名称:-)
  • 感谢 dba。您对 dgvSystems_MouseLeftButtonUp 是正确的。我在发布之前简化了代码并忘记删除它。我已经相应地编辑了代码。

标签: c# wpf


【解决方案1】:

此链接可能会为您提供一些答案 -> https://stackoverflow.com/a/15907332/16052620

唯一的改变是将绑定的 'UpdateSourceTrigger' 属性设置为 PropertyChanged。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-03
    • 2012-06-22
    • 2016-06-19
    • 2011-11-19
    • 2016-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多