繁体   English   中英

WPF+Caliburn.Micro:ComboBox 和 ListBox 未正确使用字典更新

[英]WPF+Caliburn.Micro: ComboBox and ListBox not updating with dictionary properly

我正在使用 Caliburn.micro 为正则表达式库制作 GUI,并且在大多数情况下它都有效。 但是当您尝试加载新字典或正则表达式模式时,将抛出未处理的异常并且程序崩溃。

在我的 shell 视图 XAML 中,这里是绑定到枚举键值对的字典的 ListBox。

<Label DockPanel.Dock="Top" >
            <TextBlock>Selected Pattern</TextBlock>
        </Label>
        <TextBox Name="RegexSelectionPattern"  IsReadOnly="True" cal:Message.Attach="[Event MouseDoubleClick] = [Action CopySelectedPatternToClipboard()]"  DockPanel.Dock="Top" Background="White" Width="222" Height="40" Margin="0,0,4,0" ToolTip="Double click to copy to clipboard">
        </TextBox>
        <Label DockPanel.Dock="Top">
            <TextBlock>Dictionary Selection</TextBlock>
        </Label>
        <ComboBox x:Name="Dictionaries"  SelectedValue="{Binding ActiveRegexLibrary}" IsEditable="False" Margin="0,0,4,0" SelectedValuePath="Value"  DisplayMemberPath="Key" DockPanel.Dock="Top">
        </ComboBox>
        <Label DockPanel.Dock="Top">
            <TextBlock>Pattern Selection</TextBlock>
        </Label>
        <ListBox x:Name="RegexChooser" SelectedItem="{Binding RegexSelection}" Margin="0,0,4,0"  SelectedValuePath="Value"  DisplayMemberPath="Key" DockPanel.Dock="Top">
        </ListBox>

外壳视图 这会产生左下角的三个控件,其中两个是项目列表器。

在 ShellViewModel 中, RegexChooser被绑定为一个字典,由ActiveRegexLibrary提供。 问题是

    /// <summary>
    ///  List of choosable regex patterns
    /// </summary>
    public Dictionary<string, string> RegexChooser
    {
        get
        {
            return this.ActiveRegexLibrary.dictionary;
        }
    }

当我使用该方法向该字典添加更多模式时,问题开始发生。 (或者当我尝试向上面的 ComboBox 添加新词典时。)当尝试向下滚动以查看最新问题时,程序以以下异常结束。

       Message=Information for developers (use Text Visualizer to read this):
This exception was thrown because the generator for control 'System.Windows.Controls.ListBox Items.Count:38' with name 'RegexChooser' has received sequence of CollectionChanged events that do not agree with the current state of the Items collection.  The following differences were detected:
  Accumulated count 37 is different from actual count 38.  [Accumulated count is (Count at last Reset + #Adds - #Removes since last Reset).]

One or more of the following sources may have raised the wrong events:
     System.Windows.Controls.ItemContainerGenerator
      System.Windows.Controls.ItemCollection
       MS.Internal.Data.EnumerableCollectionView
        System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]
(The starred sources are considered more likely to be the cause of the problem.)

The most common causes are (a) changing the collection or its Count without raising a corresponding event, and (b) raising an event with an incorrect index or item parameter.

The exception's stack trace describes how the inconsistencies were detected, not how they occurred.  To get a more timely exception, set the attached property 'PresentationTraceSources.TraceLevel' on the generator to value 'High' and rerun the scenario.  One way to do this is to run a command similar to the following:
   System.Diagnostics.PresentationTraceSources.SetTraceLevel(myItemsControl.ItemContainerGenerator, System.Diagnostics.PresentationTraceLevel.High)
from the Immediate window.  This causes the detection logic to run after every CollectionChanged event, so it will slow down the application.

我注意到解决此问题的创可贴方法是使用虚拟对象切换 ActiveRegexLibrary,然后将其切换回来,并且 ListBox 可以很好地显示新模式。 此外,切换到 ComboBox 中的另一个字典,然后切换回重新加载 ListView。 以编程方式刷新这些项目列表的最佳方法是什么? 推杆

NotifyOfPropertyChange(() => RegexChooser);
NotifyOfPropertyChange(() => ActiveRegexLibrary);

在 Caliburn 中通常为非列表属性所做的设置器中似乎在这里不起作用,并且因为我使用的是 Caliburn,所以我认为我不应该直接接触 VM 的视图。

我不知道你是否会看到这个答案,但我走了。

而不是使用这个:

 public Dictionary<string, string> RegexChooser { get { return this.ActiveRegexLibrary.dictionary; } }

尝试使用 BindableCollection,如下所示:

public BindableCollection<KeyValuePair<String, String>> RegexChooser
{
    get { return this.ActiveRegexLibrary.dictionary; }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM