根据另一个选择来填充一个组合框 [英] Populate one combobox based on selection of another

查看:113
本文介绍了根据另一个选择来填充一个组合框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习wpf mvvm,一直在努力,我觉得很简单,但是还是无法自行解决。



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



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



我尝试将调用添加到SelectedString属性设置器,但似乎没有被调用。我确定我错过了一些简单的东西,但是我需要一个人帮助提起面纱!



我已经尝试过其他帖子的建议,但到目前为止不成功。



以下是该视图的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
标题=主窗口高度=400宽度=800>

& DockPanel>
< Grid>
< Grid.RowDefinitions>
< RowDefinition Height =60 */>
< RowDefinition Height =282 */>
< /Grid.RowDefinitions>
<! - 在此添加其他内容 - >
< ComboBox ItemsSource ={Binding MyStrings}SelectedItem ={Binding Path = SelectedString,Mode = TwoWay}Height =23Horizo​​ntalAlignment =LeftMargin =18,24,0,0 Name =comboBox1VerticalAlignment =TopWidth =204/>
< TextBlock Text ={Binding SelectedString}Height =23Horizo​​ntalAlignment =LeftMargin =276,24,0,0Name =textBlock1VerticalAlignment =TopWidth =227 Background =#FFFAE7E7/>
< ComboBox ItemsSource ={Binding ResultStrings}Height =23Horizo​​ntalAlignment =LeftMargin =543,25,0,0Name =comboBox2VerticalAlignment =TopWidth =189 />
< / Grid>
< / DockPanel>
< / Window>

以下是视图模型:

  public class MainViewModel:ViewModelBase 
{
public MainViewModel()
{
this.MyStrings = new ObservableCollection< string>
{
一,
两,
三,
四,

};
}

public ObservableCollection< string> MyStrings {get;组; }
public ObservableCollection< string> ResultStrings {get;组;

public string SelectedString
{
get {return(string)GetValue(SelectedStringProperty); }
set
{
SetValue(SelectedStringProperty,value);
this.ResultStrings = getResultStrings(value);
}
}

//使用DependencyProperty作为SelectedString的后备存储。这使得动画,样式,绑定等...
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> {六,七,八};
}
else
{
result = new ObservableCollection< string> {九,十,十一};
}

返回结果;
}
}


解决方案

SelectedString依赖属性实现是错误的:您应该注册PropertyChangedCallback以在直接访问DP时不通知CLR属性集(请参阅 http://msdn.microsoft.com/en-us/library/system.windows.propertychangedcallback.aspx );这样,即使直接使用DP,也可以更改相关的集合。



绑定依赖属性(如 SelectedString ),WPF绑定不使用CLR属性设置器,所以你永远不会得到调用的 getResultStrings



顺便说一下,我会考虑在View Models上使用POCO方法,实现INotifyPropertyChanged:DP是一个很难写入和添加大量噪声到VM(除了对System.Windows的讨厌的依赖)。



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


I am learning wpf mvvm and have been struggling with what I feel is probably simple but have not been able to resolve on my own.

What I want is to be able to select an item in a populated combobox and then populate another combobox based on that selection. I can't seem to get the second combobox loaded in response to a selection.

I've included an example with 2 comboboxes and one textblock. When I run the app and select an item in the first combo, the textblock is updated based on the binding, but I don't know where to call the code to update the second combobox.

I tried adding the call to the SelectedString property setter, but that does not seem to ever be called. I'm sure I'm missing something simple, but I need someone to help lift the veil!

I've tried suggestions on other posts but so far I have been unsuccessful.

Here is the xaml for the view:

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

Here is the view model:

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

解决方案

The SelectedString dependency property implementation is wrong: you should register PropertyChangedCallback to be notified when the DP is accessed directly and not with the CLR property set (see http://msdn.microsoft.com/en-us/library/system.windows.propertychangedcallback.aspx); this way you can change the related collection even if the DP is used directly.

When binding against a dependency property (like SelectedString), the WPF binding doesn't use the CLR property setter, so you never get getResultStrings called.

By the way, I would consider using a POCO approach on View Models, implementing INotifyPropertyChanged: DP are a pain to write and add a lot of noise to VMs (other than a nasty dependency on System.Windows).

Have a look at this blog post for a extensive comparison: http://kentb.blogspot.com/2009/03/view-models-pocos-versus.html

这篇关于根据另一个选择来填充一个组合框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆