Silverlight Siliverlight数据绑定组合框不';t显示初始化值

Silverlight Siliverlight数据绑定组合框不';t显示初始化值,silverlight,data-binding,xaml,mvvm,combobox,Silverlight,Data Binding,Xaml,Mvvm,Combobox,我正在将视图数据绑定到viewmodel,并且无法将组合框初始化为默认值。我在绑定中使用的类的简化是 public class LanguageDetails { public string Code { get; set; } public string Name { get; set; } public string EnglishName { get; set; } public string DisplayName { get { if

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

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>

viewmodel包含以下代码

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");
  }
}
private List\u可用语言;
专用语言详细信息_选择的语言;
公共登录视图模型()
{
_availableLanguages=LanguageManager.GetLanguageDetailsForSet(BaseApp.AppLanguageSetID);
_selectedLanguage=\u availableLanguages.SingleOrDefault(l=>l.Code==“en”);
}
公共语言详细信息所选语言
{
获取{return\u selectedLanguage;}
设置
{
_selectedLanguage=值;
OnPropertyChanged(“SelectedLanguage”);
}
}
公共列表可用语言
{
获取{return\u availableLanguages;}
设置
{
_可用语言=值;
关于财产变更(“可用语言”);
}
}
在构造函数的末尾,_availableLanguages和_selectedLanguage变量均按预期设置,组合框的下拉列表包含_availableLanguages中的所有项,但所选值不会显示在组合框中。从下拉列表中选择项目将正确显示该项目,并在viewmodel中设置SelectedLanguage属性。setter中的断点显示_selectedLanguage仍然包含它初始化为的内容,直到它被值覆盖


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

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

<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>


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

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

<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>

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

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

2) 您需要将selectedlanguage的赋值移动到视图加载时。可以通过在视图上实现已加载的事件处理程序来实现。如果您希望“符合mvvm”,则应使用混合行为,将UI加载的事件映射到viewmodel命令实现,在该实现中,您将设置所选语言。

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


2) 您需要将selectedlanguage的赋值移动到视图加载时。可以通过在视图上实现已加载的事件处理程序来实现。如果您希望“符合mvvm”,那么您应该使用混合行为,将UI加载的事件映射到viewmodel命令实现,在该实现中您可以设置所选语言。

我尝试了第一个选项;它不起作用。我想避免像你的第二个建议那样使用额外的代码。我相信这应该只需要简单的绑定就可以实现,而我接受的答案所提供的解决方案证明了这一点。仅仅第一个选项是不够的。视图模型上的SelectedLanguages属性必须在视图完全构建后设置。为什么是“-1”?我只是想帮你。我很感谢你的帮助,但是投票上升/下降按钮上的工具提示对上升来说“这个答案有用”,对下降来说“这个答案不有用”。虽然您的解决方案可能会实现这一结果,但它增加了复杂性,并没有找到根本原因,即XAML属性的排序。因此,我没有发现它有用,所以我把它标记了下来。你在说什么“XAML属性的排序”?ComboBox控件上属性的顺序与当前问题的根源无关。您可以在不影响解决方案的情况下切换顺序。然而,当你实施我的两个建议时,问题就解决了。事实上,甚至在回答之前,我已经使用您的代码片段创建了一个示例项目,并且我的解决方案100%正常工作,即,在创建视图之后,默认情况下会填充组合框!更重要的是,适当的语言是有约束力的。这里问题的根源是,在视图填充combobox之前,您试图绑定它。这就是我在第二点中所说的。也就是说,有必要将绑定推迟到combobox被填充的时刻。在这里没有其他方法可以实现这个目标;它不起作用。我想避免像你的第二个建议那样使用额外的代码。我相信这应该只需要简单的绑定就可以实现,而我接受的答案所提供的解决方案证明了这一点。仅仅第一个选项是不够的。必须在创建视图后设置ViewModel上的SelectedLanguages属性