c# - WPF+Caliburn.Micro : ComboBox and ListBox not updating with dictionary properly

标签 c# .net wpf xaml caliburn.micro

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

在我的 shell View XAML 中,这里是绑定(bind)到枚举键值对的字典的 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>

ShellView 这会在左下角产生三个控件,其中两个是项目列表器。

在 ShellViewModel 中,RegexChooser 被绑定(bind)为 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);

在 setter 中,通常在 Caliburn 中为非列表属性完成的操作在这里似乎不起作用,并且因为我使用的是 Caliburn,所以我认为我不应该直接使用 VM 接触 View 。

最佳答案

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

而不是使用这个:

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

尝试使用 BindableCollection,像这样:

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

关于c# - WPF+Caliburn.Micro : ComboBox and ListBox not updating with dictionary properly,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26939561/

相关文章:

c# - AssetDatabase.Refresh 准备就绪时发出通知

c# - 如何使用自定义顺序属性对枚举进行排序?

c# - 为什么 mvcaction4 代码片段没有反应?

c# - 一个实体应该持续无知吗?

c# - 单个与多个 MemoryCache 实例

c# - 访问 ObservableCollection 中的项目绑定(bind)到 WPF DataGrid

c# - MEF 如何设法实例化作为外部程序集的内部类的导出部件?

c# - WCF 不反序列化值类型。神秘行为

c# - 出错时重试异步文件上传

c# - 将 ViewModel 传递给 UserControl