代码之家  ›  专栏  ›  技术社区  ›  Chris Dunaway

基于对另一个组合框的选择填充一个组合框

  •  3
  • Chris Dunaway  · 技术社区  · 15 年前

    我正在学习wpf mvvm,并且一直在与我觉得可能很简单的事情作斗争,但我自己还没能解决。

    我想要的是能够在填充的组合框中选择一个项目,然后基于该选择填充另一个组合框。我似乎无法加载第二个组合框来响应选择。

    我已经包含了一个包含两个组合框和一个文本块的示例。当我运行应用程序并在第一个组合框中选择一个项目时,文本块会根据绑定进行更新,但我不知道在哪里调用代码来更新第二个组合框。

    我尝试将调用添加到selectedString属性setter,但似乎从未调用过它。我肯定我错过了一些简单的东西,但我需要有人帮忙揭开面纱!

    我尝试过其他帖子的建议,但到目前为止我还是没有成功。

    以下是视图的XAML:

    <Window x:Class="ThrowAwayMVVMApp.Views.MainView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Main Window" Height="400" Width="800">
    
        <DockPanel>
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="60*" />
                    <RowDefinition Height="282*" />
                </Grid.RowDefinitions>
                <!-- Add additional content here -->
                <ComboBox ItemsSource="{Binding MyStrings}" SelectedItem="{Binding Path=SelectedString, Mode=TwoWay}" Height="23" HorizontalAlignment="Left" Margin="18,24,0,0" Name="comboBox1" VerticalAlignment="Top" Width="204" />
                <TextBlock Text="{Binding SelectedString}" Height="23" HorizontalAlignment="Left" Margin="276,24,0,0" Name="textBlock1" VerticalAlignment="Top" Width="227" Background="#FFFAE7E7" />
                <ComboBox ItemsSource="{Binding ResultStrings}"  Height="23" HorizontalAlignment="Left" Margin="543,25,0,0" Name="comboBox2" VerticalAlignment="Top" Width="189" />
            </Grid>
        </DockPanel>
    </Window>
    

    这是视图模型:

    public class MainViewModel : ViewModelBase
    {
        public MainViewModel()
        {
            this.MyStrings = new ObservableCollection<string>
                {
                    "One",
                    "Two",
                    "Three",
                    "Four",
                    "Five"
                };
        }
    
        public ObservableCollection<string> MyStrings { get; set; }
        public ObservableCollection<string> ResultStrings { get; set; }
    
        public string SelectedString
        {
            get { return (string)GetValue(SelectedStringProperty); }
            set 
            { 
                SetValue(SelectedStringProperty, value);
                this.ResultStrings = getResultStrings(value);
            }
        }
    
        // Using a DependencyProperty as the backing store for SelectedString.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SelectedStringProperty =
            DependencyProperty.Register("SelectedString", typeof(string), typeof(MainViewModel), new UIPropertyMetadata(""));
    
    
        private ObservableCollection<string> getResultStrings(string input)
        {
            ObservableCollection<string> result = null;
    
            if (input == "Three")
            {
                result = new ObservableCollection<string> { "Six", "Seven", "Eight" };
            }
            else
            {
                result = new ObservableCollection<string> { "Nine", "Ten", "Eleven" };
            }
    
            return result;
        }
    }
    
    2 回复  |  直到 15 年前
        1
  •  2
  •   Marco Amendola    15 年前

    selectedString依赖项属性实现错误:应注册propertyChangedCallback,以便在直接访问DP时得到通知,而不是使用clr属性集(请参见 http://msdn.microsoft.com/en-us/library/system.windows.propertychangedcallback.aspx );这样,即使直接使用dp,也可以更改相关集合。

    当绑定到依赖属性(如 SelectedString )wpf绑定不使用clr属性setter,因此永远不会 getResultStrings 打电话。

    顺便说一句,我会考虑在视图模型上使用POCO方法,实现inotifypropertieschanged:dp是编写的一个难题,并且会给vms增加很多噪音(除了对system.windows的严重依赖)。

    查看此博客文章进行广泛比较: http://kentb.blogspot.com/2009/03/view-models-pocos-versus.html

        2
  •  0
  •   Agies    15 年前

    尝试

    private string selectedString;
    public string SelectedString
    {
        get { return selectedString; }
        set 
        { 
            if (selectedString == value) return;
            selectedString = value;
            // Required for the UI to know the change was successful
            RaisePropertyChanged("SelectedString");
            LoadStringResults(value);
        }
    }
    
    private ObservableCollection<string> resultStrings;
    public ObservableCollection<string> ResultStrings
    {
        get { return resultStrings; }
        set 
        { 
            if (resultStrings== value) return;
            resultStrings= value;
            // Required for databinding to know that ResultStrings changed
            // Previously you changed this property without updating the UI
            RaisePropertyChanged("ResultStrings");
        }
    }
    
    private void LoadStringResults(string input)
    {
        ObservableCollection<string> result = null;
    
        if (input == "Three")
        {
            result = new ObservableCollection<string> { "Six", "Seven", "Eight" };
        }
        else
        {
            result = new ObservableCollection<string> { "Nine", "Ten", "Eleven" };
        }
    
        ResultStrings = result;
    }
    
    推荐文章