【问题标题】:Combobox value changes, but visually SelectedValue stays the same组合框值发生变化,但在视觉上 SelectedValue 保持不变
【发布时间】:2020-10-31 01:19:09
【问题描述】:

我有一个带有自定义枚举的组合框(只是真/假)。我有一个函数,如果 SelectedValue 从 false 变为 true,并且如果条件错误,它将组合框 SelectedValue 更改回 false,它会检查条件。如果您在代码中检查它,这会将 SelectedValue 更改为 false,但是当您查看 UI 时,它仍然为 true。

这是组合框的 xaml:

<ComboBox x:Name="comboEnabled1" Width="80" Height="26"
                          ItemsSource="{Binding Path=TrueFalseChoices}"
                          SelectedValue="{Binding Path=Enable1, Mode=TwoWay}"/>
            

这是视图模型

private TrueFalse _enable1 = TrueFalse.False;
    public TrueFalse Enable1
    {
        get { return _enable1; }
        set
        {
            if (_enable1 != value)
            {
                _enable1 = value;
                base.OnPropertyChanged("Enable1");
                OnEnableChanged(EventArgs.Empty);
            }
        }
    }

这是我用来检查条件的函数

public void HandleEnable(object sender, EventArgs e)
    {
        if(Enable1 == TrueFalse.True)
        {
            if(!connected)
            {
                HandleMessage("Can't enable, not connected");
                Enable1 = TrueFalse.False;
            }
            else if (!_main.CBCheck(_main.cbReason))
            {
                Enable1 = TrueFalse.False;
            }

        }
        Console.WriteLine("Enabled {0}", Enable1);

    }

我认为我更改值的速度太快了,但最后一个 Console.Writeline 每次都会产生正确的结果。

任何帮助表示赞赏!

编辑:在此处调用 Handleenable:

protected void OnEnableChanged(EventArgs e)
    {
        EventHandler handler = EnableChanged;
        if (handler != null)
            handler(this, e);
    }

在 ViewModel 函数中:

        EnableChanged += HandleEnable;

在任何其他地方更改 Enable1 都可以正常工作,只是在 HandleEnable 函数中存在问题。还尝试更改 HandleEnable 函数中的其他组合框,并且应该可以正常工作。

【问题讨论】:

  • 您如何以及何时调用 HandleEnable?你能展示一下 TrueFalseChoices 集合的方式和内容是什么
  • TrueFalseChoices 是我的自定义枚举,它包含 2 个值,真和假。 static private readonly List&lt;TrueFalse&gt; _TRUEFALSE_CHOICES = new List&lt;TrueFalse&gt;(); static MainViewModel() { _TRUEFALSE_CHOICES.Add(TrueFalse.False); _TRUEFALSE_CHOICES.Add(TrueFalse.True); }
  • 集合是私有的和静态的。如果没有静态标记扩展,您如何绑定它或帖子中缺少某些内容?
  • 很可能类似于public IEnumerable&lt;TrueFalse&gt; TrueFalseChoices =&gt; _TRUEFALSE_CHOICES;——但这并不重要。我已经回答过了,他可能已经解决了这个问题。
  • 你高估了我@Thehx 真的只是得到它。你对 neelesh 的回答完全正确

标签: c# .net xaml combobox


【解决方案1】:

如果不满足要求,我建议实际禁用 ComboBox。

但是如果你坚持在不满足条件的情况下将 Enable1 恢复为 False,你应该通过 dispatcher 正确推送通知。

set
{
    var effectiveValue = condition ? value : TrueFalse.False;
    if (effectiveValue == TrueFalse.False && value == TrueFalse.True)
        System.Windows.Threading.Dispatcher.CurrentDispatcher.BeginInvoke(
            new Action(() => base.OnPropertyChanged("Enable1"), null));
    //your regular set-code follows here
}

发生这种情况是因为 WPF 已经响应了该事件,因此在完成之前会忽略后续调用。因此,一旦当前一个通道完成,您就会立即排队另一个通道。

但我仍然建议在有效禁用 ComboBox 时禁用它。无论您怎么看,从视图模型访问调度程序都不好闻。

UPD:如果您的框架是 4.5.1+,您也可以使用 {Binding Enable1, Delay=10} 解决这个问题。

【讨论】:

  • 你能发帖吗,如何调用 HandleEnable 以便可以在调度程序调用中执行自定义逻辑,从而完成答案。
  • 感谢您的回答,实际上刚刚有时间研究这个问题。但是我正在用头撞墙,这可能是一个菜鸟问题,但是我在这一行中得到了“预期的方法名称”new Action(() =&gt; base.OnPropertyChanged("Enable1"), null)); 应该有什么?另外顺便说一句,你在 null 之后缺少一个右括号
  • 您在 ViewModel 代码中发布了 setter;我提供的调度程序调用应该是那里的第一条语句,在您的if (_enable1 != value) 之前。我再次强调:这是非常糟糕的设计。最好在 UI 中正确禁用 ComboBox,直到满足允许用户更改其选定项的条件。
  • 添加了另一种方法。只需在绑定表达式中添加延迟也可以消除问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-22
  • 2018-09-05
  • 2015-10-02
相关资源
最近更新 更多