【问题标题】:Siliverlight databound combobox doesn't display initialized valueSiliverlight 数据绑定组合框不显示初始化值
【发布时间】:2011-03-16 22:13:07
【问题描述】:

我正在将视图数据绑定到视图模型,并且无法将组合框初始化为默认值。我在绑定中使用的类的简化是

public class LanguageDetails
{
  public string Code { get; set; }
  public string Name { get; set; }
  public string EnglishName { get; set; }

  public string DisplayName
  {
    get
    {
      if (this.Name == this.EnglishName)
      {
        return this.Name;
      }
      return String.Format("{0} ({1})", this.Name, this.EnglishName);
    }
  }
}

组合框在视图的 XAML 中声明为

<ComboBox x:Name="LanguageSelector" Grid.Row="0" Grid.Column="1" 
          SelectedItem="{Binding SelectedLanguage,Mode=TwoWay}" 
          ItemsSource="{Binding AvailableLanguages}">
  <ComboBox.ItemTemplate>
    <DataTemplate>
      <TextBlock Text="{Binding DisplayName}"/>
    </DataTemplate>
  </ComboBox.ItemTemplate>
</ComboBox>

并且视图模型包含此代码

private List<LanguageDetails> _availableLanguages;
private LanguageDetails _selectedLanguage;

public LoginViewModel()
{
  _availableLanguages = LanguageManager.GetLanguageDetailsForSet(BaseApp.AppLanguageSetID);
  _selectedLanguage = _availableLanguages.SingleOrDefault(l => l.Code == "en");
}

public LanguageDetails SelectedLanguage
{
  get { return _selectedLanguage; }
  set
  {
    _selectedLanguage = value;
    OnPropertyChanged("SelectedLanguage");
  }
}

public List<LanguageDetails> AvailableLanguages
{
  get { return _availableLanguages; }
  set
  {
    _availableLanguages = value;
    OnPropertyChanged("AvailableLanguages");
  }
}

在构造函数的末尾,_availableLanguages 和 _selectedLanguage 变量都按预期设置,组合框的下拉列表包含 _availableLanguages 中的所有项目,但所选值不显示在组合框中。从下拉列表中选择一个项目会正确显示它并在视图模型中设置 SelectedLanguage 属性。 setter 中的断点表明 _selectedLanguage 仍然包含它被初始化的内容,直到它被 value 覆盖。

我怀疑我遗漏了一些小东西,但是在尝试了各种方法和大量谷歌搜索之后,我仍然感到困惑。我可以通过其他方式达到预期的结果,但我真的想掌握正确使用数据绑定的方法。

【问题讨论】:

    标签: silverlight data-binding xaml mvvm combobox


    【解决方案1】:

    您需要更改 XAML 中的绑定顺序,以便您的 ItemsSource 在 SelectedItem 之前绑定。

    <ComboBox x:Name="LanguageSelector" Width="100"  
            ItemsSource="{Binding AvailableLanguages}"
            SelectedItem="{Binding SelectedLanguage,Mode=TwoWay}">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding DisplayName}"/>
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>
    

    如果您在 SelectedLanguage 和 AvailibleLanguage 的“获取”上设置断点,您会注意到 SelectedLanguage 在您的 AvailibleLanguage 之前被命中。由于发生这种情况,因此无法设置 SelectedLanguage,因为尚未填充 ItemsSource。更改 XAML 中绑定的顺序将使 AvailibleLanguages 先被命中,然后是 SelectedLanguage。这应该可以解决您的问题。

    【讨论】:

    • 谢谢。正如您在实际看到您的答案之前所描述的那样,我通过断点发现了这一点。我不得不说,XAML 中的属性顺序很重要,这让我大吃一惊。我从没想过会是这样。
    【解决方案2】:

    1) 分配 SelectedLanguage 时,请使用公共属性 SelectedLanguage 而不是私有 _selectedLanguage,以便执行 setter,

    2) 您需要将选定语言的分配移动到视图加载的那一刻。您可以通过在视图上实现 Loaded 事件处理程序来实现。如果您想“兼容 mvvm”,那么您应该使用 Blend 行为,它将 UI 加载事件映射到您将在其中设置所选语言的 viewmodel 命令实现。

    【讨论】:

    • 我尝试了第一个选项;它没有用。我想避免您的第二个建议中的额外代码。我相信这应该可以通过简单的绑定来实现,并且我接受的答案提供的解决方案证明了这一点。
    • 仅第一个选项是不够的。 ViewModel 上的 SelectedLanguages 属性必须在视图完全构建后设置。为什么是“-1”?只是想帮忙。
    • 我感谢您尝试提供帮助,但投票向上/向下按钮上的工具提示对向上表示“此答案很有用”,而向下表示“此答案无用”。虽然您的解决方案可能会实现结果,但它会增加复杂性并且无法解决根本原因,即 XAML 属性的排序。因此我觉得它没有用,所以我把它标记下来。
    • 您在说什么“XAML 属性的排序”? ComboBox 控件上的属性顺序与当前问题的根源无关。您可以切换顺序而不影响解决方案。但是,当您实施我的两个建议时,问题就解决了。实际上,即使在回答之前,我已经使用您的 sn-ps 创建了一个示例项目,并且我的解决方案可以 100% 正常工作,即。创建视图后默认填充组合框!
    • 而且,更重要的是要绑定正确的语言。这里问题的根源是您试图在组合框被视图填充之前绑定它。这就是我在第 2 点中要解决的问题。也就是说,有必要将绑定推迟到组合框被填充的那一刻。这里没有其他方法可以实现目标。
    猜你喜欢
    • 1970-01-01
    • 2011-11-27
    • 2013-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-30
    • 2013-07-26
    • 2015-05-24
    相关资源
    最近更新 更多