user83493
user83493

Reputation: 213

WPF: Binding to ComboBox SelectedItem

I have a UserControl with ComboBox that based on XML data:

<Root>
<Node Background="Yellow" Foreground="Cyan" Image="1.ico" Property="aaaa" Value="28" />
<Node Background="SlateBlue" Foreground="Black" Image="2.ico" Property="bbbb" Value="2.5" />
<Node Background="Teal" Foreground="Green" Image="3.ico" Property="cccc" Value="4.0" />
<Node Background="Yellow" Foreground="Red" Image="4.ico" Property="dddd" Value="0" /></Root>

Here is the UserControl XAML:

<UserControl x:Class="xxxxxxxx.MyComboBox"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         x:Name="myComboBoxControl">
<UserControl.Resources>
    <DataTemplate x:Key="dataTemplateNode">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" MinWidth="20"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="Auto" MinWidth="20"/>
            </Grid.ColumnDefinitions>
            <Border Background="{Binding XPath=@Background}" Grid.Column="0">
                <Image Source="{Binding XPath=@Image}" 
                       Width="16" 
                       Height="16" 
                       Margin="3" />
            </Border>
            <Border Background="{Binding XPath=@Background}" Grid.Column="1">
                <TextBlock Foreground="{Binding XPath=@Foreground}" 
                           Margin="3"
                           Text="{Binding XPath=@Property}" />
            </Border>
            <Border Background="{Binding XPath=@Background}" Grid.Column="2">
                <TextBlock Foreground="{Binding XPath=@Foreground}" 
                           Margin="3" 
                           FontWeight="Bold"
                           Text="{Binding XPath=@Value}" />
            </Border>
        </Grid>
    </DataTemplate>

    <XmlDataProvider x:Key="xmlNodeList" 
                     Source="/data/Combo.xml" 
                     XPath="/Root/Node"/>
</UserControl.Resources>

<ComboBox Name="myComboBox" 
          ItemsSource="{Binding Source={StaticResource xmlNodeList}}" 
          ItemTemplate="{StaticResource dataTemplateNode}"
          HorizontalContentAlignment="Stretch" /></UserControl>

In the MainForm.xaml I have a TextBox that I want to bind to the my UserControl SelectedItem.

<StackPanel Orientation="Horizontal">
<local:MyComboBox1 x:Name="comboBoxST" />
<TextBox x:Name="textBoxST"/></StackPanel>

I will glad if you will guid me how to do that.

Thanks in advance!

Upvotes: 6

Views: 39756

Answers (3)

Bishop
Bishop

Reputation: 1126

For what it's worth, I preferred Sergey's earlier approach better. However, in my scenario, I had a label instead of a textbox but this worked for me:

    <Label x:Name="labelST" Content="{Binding ElementName=comboBoxST, Path=SelectedValue}"/>

Spaciba, Sergey.

Upvotes: 5

Sergey Aldoukhov
Sergey Aldoukhov

Reputation: 22744

The trick here is that when you have to bind to the SelectedItem on an ItemControl bound to XML, the selected item itself is an XmlElement, and you have to use XPath to get to the needed element/attribute.

The easiest way to achieve this is to use DataContext:

<TextBox x:Name=textBoxST 
    DataContext="{Binding ElementName=comboBoxST, Path=SelectedItem}" 
    Text="{Binding XPath=@Value}"/>

Upvotes: 15

Sergey Aldoukhov
Sergey Aldoukhov

Reputation: 22744

The answer posted above was for the case of a list box placed directly on the form. In case of UserControl and templated ComboBox, I would avoid pure xml binding - too many factors can break it. Instead, use this code to create a dependency property:

  public MyComboBox()
    {
        InitializeComponent();
        myComboBox.SelectionChanged += MyComboBoxSelectionChanged;
    }

    void MyComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        SetValue(SelValueProperty, ((XmlElement)e.AddedItems[0]).Attributes["Value"].Value);
    }

    public static readonly DependencyProperty SelValueProperty =
        DependencyProperty.Register("SelValue", typeof(string), typeof(MyComboBox),
            new FrameworkPropertyMetadata(""));

And binding is simple then:

<TextBox x:Name=textBoxST Text="{Binding ElementName=comboBoxST, Path=SelValue}"/>

Upvotes: 1

Related Questions