WPF, свойство, привязанное к зависимому ComboBox, всегда дает начальное значение - PullRequest
1 голос
/ 13 августа 2010

У меня есть ComboBox, который должен зависеть от значения другого ComboBox. Эта часть уже работает с обновлением зависимого ComboBox при выборе нового значения в независимом ComboBox:

<!-- 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" />

В этом классе C # у меня есть:

public MyUserControlConstructor()
{
    MyViewModelInstance= new MyViewModel();
    DataContext = MyViewModelInstance;
}

А в 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));
}

Когда я меняю зависимый ComboBox (Компонент), он, конечно же, обнаруживается с новым значением в моем приложении. Однако, когда я нажимаю кнопку, вызывающую отображение значения свойства Component, это всегда начальное значение, а не значение, которое я только что выбрал в ComboBox. Я думаю, что в моем XAML должна быть ошибка. Для C # я пытался следовать комбинации , и , это руководство . Как связать мой зависимый ComboBox со значениями XML, вложенными в SelectedItem независимого ComboBox, но все же обновить свойство Component в моем классе?

Редактировать: Я подозреваю, что все шатко, потому что я установил DataContext для зависимого ComboBox в двух местах: сначала в конструкторе в C #, для моей модели представления, а затем в XAML, до DataContext="{Binding SelectedItem, ElementName=cbo_product}".

Редактировать: Я устанавливал начальные значения в конструкторе для своего класса модели представления. Когда я беру начальное значение для свойства Component, то даже после изменения выбранного значения в зависимом ComboBox я все равно не получаю значения из свойства Component. Это в значительной степени просто повторяет то, что я уже знал: зависимый ComboBox привязан к независимому ComboBox (то есть получает данные из независимого ComboBox, то есть), но не к свойству Component.

Редактировать: по запросу, вот пример моего XML:

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

Редактировать: Я предполагаю, что MultiBinding будет полезным, после просмотра это и это .

Редактировать: Похоже, я смогу заставить зависимого ComboBox работать без установки DataContext, просто используя ItemsSource:

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

Однако это не работает: зависимый ComboBox пуст вместо отображения всех имен Компонентов.

1 Ответ

0 голосов
/ 16 августа 2010

Я нашел способ обойти это, включив настройку ItemsSource в C # вместо 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"/>

В C # обработчик события для изменения независимого ComboBox:

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

Теперь свойство Component в моем классе модели представления, с которым мой зависимый ComboBox связан в XAML, заполняется значением, выбранным в зависимом ComboBox, потому что мне не нужно было изменять DataContext зависимого ComboBox.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...