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

Wpf 基于对另一个组合框的选择填充一个组合框,wpf,data-binding,mvvm,Wpf,Data Binding,Mvvm,我正在学习wpf mvvm,一直在努力解决我觉得可能很简单但无法自己解决的问题 我想要的是能够在填充的组合框中选择一个项目,然后基于该选择填充另一个组合框。我似乎无法加载第二个组合框来响应选择 我已经包括了一个带有2个组合框和一个文本块的示例。当我运行应用程序并在第一个组合框中选择一个项目时,textblock会根据绑定进行更新,但我不知道在哪里调用代码来更新第二个组合框 我尝试将调用添加到SelectedString属性设置器,但似乎从未调用过。我肯定我错过了一些简单的事情,但我需要有人帮我揭

我正在学习wpf mvvm,一直在努力解决我觉得可能很简单但无法自己解决的问题

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

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

我尝试将调用添加到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"
    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;
    }
}
public类MainViewModel:ViewModelBase
{
公共主视图模型()
{
this.MyStrings=新的ObservableCollection
{
“一个”,
“两个”,
“三”,
“四”,
“五个”
};
}
公共observeCollection MyStrings{get;set;}
公共ObservableCollection结果字符串{get;set;}
公共字符串SelectedString
{
获取{return(string)GetValue(SelectedStringProperty);}
设置
{ 
SetValue(SelectedStringProperty,value);
this.ResultStrings=getResultStrings(值);
}
}
//使用DependencyProperty作为SelectedString的后备存储。这将启用动画、样式、绑定等。。。
公共静态只读从属属性SelectedStringProperty=
DependencyProperty.Register(“SelectedString”、typeof(string)、typeof(MainViewModel)、new UIPropertyMetadata(“”);
私有ObservableCollection GetResultString(字符串输入)
{
ObservableCollection结果=空;
如果(输入=“三”)
{
结果=新的可观察集合{“六”、“七”、“八”};
}
其他的
{
结果=新的可观察集合{“九”、“十”、“十一”};
}
返回结果;
}
}

SelectedString依赖项属性实现错误:您应该注册PropertyChangedCallback,以便在直接访问DP时收到通知,而不是使用CLR属性集(请参阅);这样,即使直接使用DP,也可以更改相关集合

当对依赖项属性(如
SelectedString
)进行绑定时,WPF绑定不使用CLR属性设置器,因此永远不会调用
getResultString

顺便说一下,我会考虑在POCO方法上使用视图模型,实现IntIfyProfiTyPrime:DP是一个痛苦的写入和添加大量的噪声到VMS(除了一个讨厌的依赖于系统.Windows)。 请看这篇博文进行广泛的比较:

试试看

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;
}
私有字符串selectedString;
公共字符串SelectedString
{
获取{return selectedString;}
设置
{ 
if(selectedString==value)返回;
selectedString=值;
//UI需要知道更改成功
RaisePropertyChanged(“SelectedString”);
加载结果(值);
}
}
私有可观察收集结果字符串;
公共可见收集结果字符串
{
获取{return resultStrings;}
设置
{ 
if(resultString==value)返回;
结果字符串=值;
//数据绑定需要知道ResultString已更改
//以前您在不更新UI的情况下更改了此属性
RaisePropertyChanged(“结果字符串”);
}
}
私有void LoadStringResults(字符串输入)
{
ObservableCollection结果=空;
如果(输入=“三”)
{
结果=新的可观察集合{“六”、“七”、“八”};
}
其他的
{
结果=新的可观察集合{“九”、“十”、“十一”};
}
结果字符串=结果;
}

为什么要在ViewModel中声明DP,而DP通常要在绑定到的控件中声明?