WinForms DateTimePicker在Linux Wine下设置Checked=false失效问题求助
修复Wine 8下WinForms DateTimePicker Checked属性无法设为false的问题
这是Wine对WinForms DateTimePicker控件的兼容性bug,以下是几种可行的修复方案:
方案1:强制控件状态同步与重绘
Wine的控件渲染层可能未正确响应Checked属性变更,设置后手动触发控件更新:
private void buttonSetFalse_Click(object sender, EventArgs e) { MessageBox.Show($"Before: {this.dateTimePicker1.Value} {this.dateTimePicker1.Checked}"); dateTimePicker1.Checked = false; // 强制同步UI与状态 dateTimePicker1.Update(); dateTimePicker1.Refresh(); MessageBox.Show($"After: {this.dateTimePicker1.Value} {this.dateTimePicker1.Checked}"); }
如果上述代码无效,可尝试先切换状态再设置,触发Wine内部的状态更新逻辑:
dateTimePicker1.Checked = true; dateTimePicker1.Checked = false; dateTimePicker1.Refresh();
方案2:直接调用Win32 API修改状态
WinForms的DateTimePicker封装了原生Win32控件,通过发送Win32消息可绕过Wine的.NET封装层问题:
首先导入必要的Win32 API定义:
using System.Runtime.InteropServices; private const int DTM_FIRST = 0x1000; private const int DTM_SETSYSTEMTIME = DTM_FIRST + 2; private const int GDT_NONE = 0x0001; [StructLayout(LayoutKind.Sequential)] private struct SYSTEMTIME { public ushort wYear; public ushort wMonth; public ushort wDayOfWeek; public ushort wDay; public ushort wHour; public ushort wMinute; public ushort wSecond; public ushort wMilliseconds; } [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, ref SYSTEMTIME lParam);
然后替换原来的Checked设置代码:
private void buttonSetFalse_Click(object sender, EventArgs e) { MessageBox.Show($"Before: {this.dateTimePicker1.Value} {this.dateTimePicker1.Checked}"); // 发送消息取消选中状态 SYSTEMTIME st = new SYSTEMTIME(); SendMessage(dateTimePicker1.Handle, DTM_SETSYSTEMTIME, (IntPtr)GDT_NONE, ref st); // 手动同步WinForms属性缓存 dateTimePicker1.Checked = false; MessageBox.Show($"After: {this.dateTimePicker1.Value} {this.dateTimePicker1.Checked}"); }
方案3:使用自定义组合控件
如果前两种方案都无法解决问题,可用CheckBox和DateTimePicker组合实现相同功能,完全绕过原生控件的兼容性问题:
public class DateTimePickerWithCheck : Panel { private readonly CheckBox _checkBox = new CheckBox(); private readonly DateTimePicker _dateTimePicker = new DateTimePicker(); public DateTimePickerWithCheck() { _checkBox.Text = string.Empty; _checkBox.Dock = DockStyle.Left; _checkBox.CheckedChanged += (s, e) => { _dateTimePicker.Enabled = _checkBox.Checked; OnCheckedChanged(EventArgs.Empty); }; _dateTimePicker.Dock = DockStyle.Fill; Controls.Add(_dateTimePicker); Controls.Add(_checkBox); } public bool Checked { get => _checkBox.Checked; set => _checkBox.Checked = value; } public DateTime Value { get => _dateTimePicker.Value; set => _dateTimePicker.Value = value; } // 暴露需要的DateTimePicker属性,例如Format、ShowUpDown等 public DateTimePickerFormat Format { get => _dateTimePicker.Format; set => _dateTimePicker.Format = value; } public event EventHandler CheckedChanged; protected virtual void OnCheckedChanged(EventArgs e) { CheckedChanged?.Invoke(this, e); } }
使用时直接替换原有的DateTimePicker即可,用法与原生控件一致。
内容的提问来源于stack exchange,提问作者egeo
相关产品推荐
相关产品推荐

