【问题标题】:ComboBox SelectedItem not set with x:Bind未使用 x:Bind 设置 ComboBox SelectedItem
【发布时间】:2017-08-06 12:15:03
【问题描述】:

我试图弄清楚如果我与ItemsSource="{x:Bind [source]}" 绑定,为什么我不能在我的组合框上设置初始SelectedItem 值。
这个 xaml 工作

<ComboBox 
        ItemsSource="{Binding Sites, Mode=OneWay}"
        SelectedItem="{x:Bind ViewModel.SelectedContractSite, Mode=TwoWay}"/> 

但是当我更改为以下 xaml 时,ComboBox 包含站点,但未将 SelectedItem 显示为默认值。 (事实上​​,它似乎在视野中闪烁然后消失)。

<ComboBox 
        ItemsSource="{x:Bind ViewModel.Sites, Mode=OneWay}"
        SelectedItem="{x:Bind ViewModel.SelectedContractSite, Mode=TwoWay}"/>

这里是 ViewModel 中的相关代码。 (我缩写了长长的站点列表。)

public List<string> Sites
{
    get
    {
        return new List<string>()
        {                
            "Miami",                
            "Texas"
        };
    }
}

private string _selectedContractSite = "Texas";
public string SelectedContractSite
{
    get
    {
        return _selectedContractSite;
    }
    set
    {
        Set(ref _selectedContractSite, value);
    }
}

感谢您的帮助!

【问题讨论】:

  • 试试SelectedItem="{x:Bind SelectedContractSite, Mode=TwoWay}"。我的假设是,ViewModel 已经分配为ItemsSource,所以它应该只是任何ItemsBinding 的财产。同样,只是一个假设。
  • @AVKNaidu,感谢您的建议,但没有奏效。如果没有包含 ViewModel,绑定路径将无法解析。

标签: c# xaml combobox uwp uwp-xaml


【解决方案1】:

此问题似乎与您未显示的代码有关。 (为了将来参考,请参阅https://stackoverflow.com/help/mcve 以消除在回答未来问题时的猜​​测。)

如果我创建这样的视图模型

public class ViewModel : INotifyPropertyChanged
{
    public List<string> Sites
    {
        get
        {
            return new List<string>()
            {
                "Miami",
                "Texas"
            };
        }
    }

    private string _selectedContractSite = "Texas";

    public string SelectedContractSite
    {
        get
        {
            return _selectedContractSite;
        }
        set
        {
            if (_selectedContractSite != value)
            {
                _selectedContractSite = value;
                OnPropertyChanged(nameof(SelectedContractSite));
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

然后像这样设置代码隐藏:

    public MainPage()
    {
        this.InitializeComponent();

        this.ViewModel = new ViewModel();
    }

    public ViewModel ViewModel { get; set; }

那么下面的 XAML 按预期工作

<ComboBox ItemsSource="{x:Bind ViewModel.Sites, Mode=OneWay}"
          SelectedItem="{x:Bind ViewModel.SelectedContractSite, Mode=TwoWay}" />

注意。我正在使用 x:Bind 并在两个绑定路径中引用 ViewModel。

我怀疑您的困惑在于x:Bind 和Binding 之间的区别。
对于x:Bind,绑定路径的根是带有绑定的控件所在的页面。
对于Binding,绑定路径的根是控件所在页面的DataContext。
将两者混合可能会令人困惑。如果您确实需要使用两者的组合,请在页面构造函数中设置 this.DataContext = this;,以便它们都指向同一事物。

【讨论】:

  • 正在用准确的解释和例子写我的答案。 +1。
  • 谢谢。我会深入挖掘。你写的代码看起来和我的一模一样,但是其中一些(设置 ViewModel,实现 INotifyPropertyChanged)被封装在 Template10 框架中,所以细节可能是魔鬼。
【解决方案2】:

为什么要在 Sites 属性的 getter 中创建一个新的 List&lt;string&gt;?

尝试只创建一次源集合一次:

public List<string> Sites { get; } = new List<string>() { "Miami", "Texas" };

【讨论】:

    猜你喜欢
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-30
    • 2011-06-24
    相关资源
    最近更新 更多