【发布时间】: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 是正确的。我在发布之前简化了代码并忘记删除它。我已经相应地编辑了代码。