【问题标题】:ComboBox DataContex not updated property which is placed inside the ContentControl (UWP)?ComboBox DataContex 未更新放置在 ContentControl (UWP) 内的属性?
【发布时间】:2017-09-08 10:56:00
【问题描述】:

我在ContentTemplateContentControl 中使用了ComboBox。最初,我在后面的代码中将DataContext (Profession1) 与ContentControl 的内容属性绑定。

然后我在运行时更改ComboBox 的值。之后,在运行时将ContentControlDataContext 更改为Profession2。在这种情况下,ComboBox DataContext 不会更改,之前的 DataContextSelectedItem 值也设置为 null。

我认为这是 MSControl 中的一个问题。请任何建议您的想法来解决此问题。

请参考以下代码:

查看:

    <Page.Resources>
        <local:MainPageViewModel x:Key="datacontent"></local:MainPageViewModel>
    </Page.Resources>
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
          Margin="10">
        <ContentControl x:Name="contentControl" >
            <ContentControl.ContentTemplate>
                <DataTemplate>
                    <ComboBox x:Name="comboBox"
                              ItemsSource="{Binding Professions}"
                              SelectedItem="{Binding Profession, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"                                     
                              HorizontalAlignment="Stretch"></ComboBox>
                </DataTemplate>
            </ContentControl.ContentTemplate>
        </ContentControl>
         <Button Click="Button_Click_2" Content="Change DataContext" Width="100" Height="50"></Button>
     </Grid>
</Page>

模型和视图模型:

  public class MainPageViewModel
    {
        public MainPageViewModel()
        {            
            Profession1 = new Person();
            Profession2 = new Person();                      
          private Person profession1;

        public Person Profession1
        {
            get { return profession1; }
            set { this.profession1 = value; }
        }

        private Person profession2;

        public Person Profession2
        {
            get { return profession2; }
            set { this.profession2 = value; }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

    }

    public class Person : INotifyPropertyChanged
    {
        public Person()
        {
            _professions = new List<string>();
            _professions.Add("Lawyer");
            _professions.Add("Politician");
            _professions.Add("Other");         
        }

        private string _profession;
        public string Profession
        {
            get
            {
                if (string.IsNullOrWhiteSpace(_profession))
                {
                    // _profession = _professions.LastOrDefault();
                }
                return _profession;
            }
            set
            {
                if (_profession != value)
                {
                    _profession = value;
                    NotifyPropertyChanged("Profession");
                }
            }
        }      

        private List<string> _professions;

        public List<string> Professions
        {
            get
            {
                return _professions;
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }   

代码背后:

public sealed partial class MainPage : Page
    {
        Binding binding;
        public MainPage()
        {
            this.InitializeComponent();
            var datacontent = (this.Resources["datacontent"] as MainPageViewModel);
            this.UpdateBinding1(this.contentControl, datacontent);
        }         

        public void UpdateBinding1(FrameworkElement contentcontrol, object datacontext)
        {
            binding = new Binding();
            binding.Path = new PropertyPath("Profession1");
            binding.Mode = BindingMode.TwoWay;
            binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            binding.Source = datacontext;  // view model
            BindingOperations.SetBinding(contentcontrol, ContentControl.ContentProperty, binding);
        }

        public void UpdateBinding(FrameworkElement contentcontrol, object datacontext)
        {
            binding = new Binding();
            binding.Path = new PropertyPath("Profession2");
            binding.Mode = BindingMode.TwoWay;
            binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            binding.Source = datacontext;  // view model
            BindingOperations.SetBinding(contentcontrol, ContentControl.ContentProperty, binding);
        }

       private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            var datacontext = (this.Resources["datacontent"] as MainPageViewModel);
            this.UpdateBinding(this.contentControl,datacontext);
        }
}

【问题讨论】:

    标签: c# combobox uwp uwp-xaml


    【解决方案1】:

    之后,在运行时将 ContentControl 的 DataContext 更改为 Profession2。

    绑定路径确实从Profession1 更新为Profession2。并且更新了ComboBoxItemsSource。但是由于您将Profession1Profession2 定义为相同的值,因此看起来绑定源没有更新。请将它们设置为不同的值以检查结果。例如,更新您的MainViewModel 如下:

    public class MainPageViewModel
    {
        List<string> Profession1list=new List<string>() { "Lawyer", "Politician", "Other" };
        List<string> Profession2list = new List<string>() { "Lawyer2", "Politician2", "Other2" };
        public MainPageViewModel()
        {
            Profession1 = new Person(Profession1list);
            Profession2 = new Person(Profession2list);
        }
          private Person profession1;
    
        public Person Profession1
        {
            get { return profession1; }
            set { this.profession1 = value; }
        }
    
        private Person profession2;
    
        public Person Profession2
        {
            get { return profession2; }
            set { this.profession2 = value; }
        }
    
       ...
    
    }
    
    public class Person : INotifyPropertyChanged
    {
        public Person(List<string> Professionlist)
        {
            _professions = new List<string>();
            foreach(string item in Professionlist)
            {
                _professions.Add(item);
            }
    
            //_professions.Add("Lawyer");
            //_professions.Add("Politician");
            //_professions.Add("Other");
        }     
    
        private List<string> _professions;
    
        public List<string> Professions
        {
            get
            {
                return _professions;
            }
        }
      ...
    
    }
    

    在这种情况下,ComboBox DataContext 没有改变,SelectedItem 值之前的 DataContext 也设置为 null。

    由于ComboBoxItemsSource是通过重新绑定更新的,所以SelectedItem被清除了。

    我的测试环境是 OS build 15063。更多细节请参考Data binding overview。如果您详细说明您用于此功能的场景,我们可能会为此提供更好的实践。例如,避免更新绑定路径以满足需求,而是通过其他方式。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-09
    • 1970-01-01
    • 2018-02-17
    • 1970-01-01
    • 2020-09-13
    • 1970-01-01
    • 2017-07-23
    相关资源
    最近更新 更多