Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF,绑定到依赖组合框的属性始终提供初始值_C#_Wpf_Data Binding_Xaml_Combobox - Fatal编程技术网

C# WPF,绑定到依赖组合框的属性始终提供初始值

C# WPF,绑定到依赖组合框的属性始终提供初始值,c#,wpf,data-binding,xaml,combobox,C#,Wpf,Data Binding,Xaml,Combobox,我有一个组合框,它需要依赖于另一个组合框的值。当在独立的组合框中选择一个新值时,此部分已经工作,相关的组合框将刷新: <!-- Independent --> <ComboBox Height="23" HorizontalAlignment="Left" Grid.Row="2" Grid.Column="2" x:Name="cbo_product" VerticalAlignment="Center" Width="120" Ite

我有一个
组合框
,它需要依赖于另一个
组合框
的值。当在独立的组合框中选择一个新值时,此部分已经工作,相关的组合框将刷新:

<!-- Independent -->
<ComboBox Height="23" HorizontalAlignment="Left" Grid.Row="2" Grid.Column="2"
          x:Name="cbo_product" VerticalAlignment="Center" Width="120"
          ItemsSource="{Binding Source={StaticResource productsXml}}"
          DisplayMemberPath="@name" SelectedValuePath="@name"
          SelectionChanged="cbo_product_SelectionChanged"
          SelectedValue="{Binding Path=Product}" />

<!-- Dependent -->
<ComboBox Height="23" HorizontalAlignment="Left" Grid.Row="3" Grid.Column="2"
          x:Name="cbo_component" VerticalAlignment="Center" Width="201"
          DataContext="{Binding SelectedItem, ElementName=cbo_product}"
          ItemsSource="{Binding XPath=Components/Component}"
          DisplayMemberPath="@name" SelectedValuePath="@name"
          SelectedValue="{Binding Path=Component}"
          SelectionChanged="cbo_component_SelectionChanged" />
MyViewModel
中,我有:

public string Component
{
    get { return _component; }
    set
    {
        if (value == _component)
        {
            return;
        }
        _component = value;
        onPropertyChanged(PropertyNames.Component);
    }
}

private void onPropertyChanged(PropertyNames fieldName)
{
    if (null == PropertyChanged)
    {
        return;
    }
    string propertyName = Enum.GetName(typeof(PropertyNames), fieldName);
    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
当我更改依赖的
组合框(组件)时,它当然会在我的应用程序中显示新值。但是,当我点击一个按钮以显示
组件
属性的值时,它始终是初始值,而不是我刚才在
组合框
中选择的值。我想我的XAML中一定有错误。对于C#,我尝试遵循和的组合。如何将依赖的
组合框
绑定到嵌套在独立的
组合框
SelectedItem
中的XML值,但仍然更新类中的
组件
属性

Edit:我怀疑事情是不可靠的,因为我在两个地方为依赖的
ComboBox
设置了
DataContext
:第一个是在C#中的构造函数中,到我的视图模型,第二个是在XAML中,到
DataContext=“{Binding SelectedItem,ElementName=cbo_product}”

编辑:我一直在为视图模型类设置构造函数中的初始值。当我取出
组件
属性的初始值时,即使我更改了dependent
组合框中的选定值
,我仍然无法从
组件
属性中获得任何值。这几乎是重复了我已经知道的:依赖的
组合框
绑定到独立的
组合框
(它从独立的
组合框
)获取数据,但不绑定到
组件
属性

编辑:根据请求,以下是我的XML示例:

<Products xmlns="">
  <Product name="Awesomeness">
    <Components>
      <Component name="Component of Glory"/>
      <Component name="Component of Doom"/>
    </Components>
  </Product>
</Products>

但是,这不起作用:依赖的组合框是空的,而不是显示所有的组件名称。

我发现解决这个问题的方法是在C#中设置ItemsSource,而不是XAML,我不希望这样做。然而,它是有效的,经过一天半的努力,这是我想到的最好的了

在XAML中:

<!-- Independent -->
<ComboBox Height="23" HorizontalAlignment="Left" Grid.Row="2" Grid.Column="2"
          x:Name="cbo_product" VerticalAlignment="Center" Width="120"
          ItemsSource="{Binding Source={StaticResource productsXml}}"
          DisplayMemberPath="@name" SelectedValuePath="@name"
          SelectionChanged="cbo_product_SelectionChanged"
          SelectedItem="{Binding Path=ProductNode}"
          SelectedValue="{Binding Path=Product}" />

<!-- Dependent -->
<ComboBox Height="23" HorizontalAlignment="Left" Grid.Row="3" Grid.Column="2"
          x:Name="cbo_component" VerticalAlignment="Center" Width="201"
          DisplayMemberPath="@name" SelectedValuePath="@name"
          SelectedValue="{Binding Path=Component, Mode=TwoWay}"
          SelectionChanged="cbo_component_SelectionChanged"/>

现在,我的视图模型类中的
组件
属性,我的依赖组合框
在XAML中绑定到该属性,使用在依赖的
组合框中选择的值填充,因为我不必更改依赖的
组合框的
DataContext

如果您概述了数据(XML?),会更容易理解。@Henk:righto。用一个样本更新了我的问题。
<ComboBox Height="23" HorizontalAlignment="Left" Grid.Row="3" Grid.Column="2"
                      x:Name="cbo_component" VerticalAlignment="Center" Width="201"
                      ItemsSource="{Binding ElementName=cbo_product, Path=SelectedItem,
                          XPath=Components/Component}"
                      DisplayMemberPath="@name" SelectedValuePath="@name"
                      SelectedValue="{Binding Path=Component}"
                      SelectionChanged="cbo_component_SelectionChanged"/>
<!-- Independent -->
<ComboBox Height="23" HorizontalAlignment="Left" Grid.Row="2" Grid.Column="2"
          x:Name="cbo_product" VerticalAlignment="Center" Width="120"
          ItemsSource="{Binding Source={StaticResource productsXml}}"
          DisplayMemberPath="@name" SelectedValuePath="@name"
          SelectionChanged="cbo_product_SelectionChanged"
          SelectedItem="{Binding Path=ProductNode}"
          SelectedValue="{Binding Path=Product}" />

<!-- Dependent -->
<ComboBox Height="23" HorizontalAlignment="Left" Grid.Row="3" Grid.Column="2"
          x:Name="cbo_component" VerticalAlignment="Center" Width="201"
          DisplayMemberPath="@name" SelectedValuePath="@name"
          SelectedValue="{Binding Path=Component, Mode=TwoWay}"
          SelectionChanged="cbo_component_SelectionChanged"/>
private void cbo_product_SelectionChanged(object sender,
    SelectionChangedEventArgs e)
{
    // Set ItemsSource of dependent ComboBox
    cbo_component.ItemsSource = getChildNodesFromComboBox(
        sender as ComboBox, "Components/Component"
    );
    cbo_component.SelectedIndex = 0;
}

// Helper method to do XPath query and get child nodes from selected value of
// independent ComboBox
private XmlNodeList getChildNodesFromComboBox(ComboBox comboBox,
    string xpath)
{
    if (null == comboBox)
    {
        return null;
    }
    var xml = comboBox.SelectedItem as XmlElement;
    if (null == xml)
    {
        return null;
    }
    return xml.SelectNodes(xpath);
}