1

How can I make a binding to one instance of a class? I have a combobox and if I change the selectedItem in the combobox two 2 input field's should be fillied with the propertys of the instance of the object.

Here is my wpf code:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>

    <TextBlock Text="Bearbeiten:" Style="{StaticResource TextBlockHeader}" Grid.Row="0"/>
    <ComboBox ItemsSource="{Binding LinkList}" DisplayMemberPath="DisplayName" Style="{StaticResource defaultComboBox}" Grid.Row="1"/>

    <Separator Style="{StaticResource defaultSeperator}" Grid.Row="2"/>

    <TextBlock Text="DisplayName:" Style="{StaticResource TextBlockHeader}" Grid.Row="3"/>
    <TextBox Name="linkDisplayName" Style="{StaticResource NormalTextBox}" Grid.Row="4"/>

    <TextBlock Text="URL" Style="{StaticResource TextBlockHeader}" Grid.Row="5"/>
    <TextBox Name="linkUrl" Style="{StaticResource LargeTextBox}" Grid.Row="6"/>
</Grid>

I've set the DataContext in the codebehind file (mainWindow.xaml.cs). Here is the code of the file:

public class mainWindow : MetroWindow
{
    public LinkManager LinkManager { get; set; }

    public mainWindow()
    {
        InitializeComponent();
        this.DataContext = this.LinkManager;
    }
}

The LinkManager.cs:

public class LinkManager
{
    public ObservableCollection<Link> LinkList { get; set; }
}

And at the end the Link.cs

    public class Link
    {
        private string _displayName;
        public string DisplayName
        {
            get { return this._displayName; }
            set { this._displayName = value; }
        }

        private string _url;
        public string Url
        {
            get { return this._url; }
            set { this._url = value; }
        }
    }

The ComboBox binding is working well:

FirstImage

but the inputfields are still empty (that's logic...). How can I fill them with the propertys of the selected instance of the object in the combobox?

SecondImage

Any Suggestions? Thanks!

myName
  • 11
  • 1
  • where is combo box selection changed ? – Muds Oct 20 '15 at 08:48
  • I dont have it. I need one? – myName Oct 20 '15 at 08:50
  • well, your combobox needs to tell when an item is changed, only then you can get the object from your combobox and set its properties to your next 2 controls, makes sense ? – Muds Oct 20 '15 at 08:51
  • Yeha, it makes sense. But a twoway binding would be awesome (that if a value is changed the property will change too. With your solution i need a save button too, that set the new values of the property's, correct? – myName Oct 20 '15 at 08:56
  • no, just bind a property with SelectedItem of combobox, and in setter of that property do your stuff – Muds Oct 20 '15 at 08:57
  • Use the thinking in this thread: http://stackoverflow.com/questions/2012460/wpf-binding-to-listbox-selecteditem – DanL Oct 20 '15 at 08:58
  • @Muds ok. I added now an SelectionChanged event. You can see the code here: http://collabedit.com/j8f9c (it's easier to read). If i change the selection of the combobox, the inputfields will get the value of the properties. Can you explain your last comment a bit more. It would be nice! – myName Oct 20 '15 at 09:07

1 Answers1

0

Without a good, minimal, complete code example that clearly illustrates your question, it's hard to know for sure what the best solution would be. That said…

It seems to me that an appropriate to address your apparent need would be to set up your bindings differently, so that you can just directly bind to the SelectedItem property to update the edit fields and their bindings. I.e. instead of setting the DataContext for the benefit of the ComboBox.ItemsSource binding, bind the DataContext to the ComboBox.SelectedItem, and then use that context for bindings in the edit fields.

That way, any time the selected item is changed by the user, WPF will automatically connect things appropriately to your needs.

Here is a code example that illustrates what I mean:

XAML:

<Window x:Class="TestSO33231850BindDataContext.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        x:Name="mainWindow1"
        Title="MainWindow" Height="350" Width="525">

  <!-- Bind container's DataContext to the SelectedItem -->
  <Grid DataContext="{Binding SelectedItem, ElementName=comboBox1}">

    <Grid.Resources>
      <Style TargetType="TextBox">
        <Setter Property="Padding" Value="5, 0"/>
        <Setter Property="Margin" Value="5, 0"/>
        <Setter Property="Width" Value="100"/>
        <Setter Property="HorizontalAlignment" Value="Left"/>
      </Style>
    </Grid.Resources>

    <Grid.RowDefinitions>
      <RowDefinition Height="Auto"/>
      <RowDefinition Height="Auto"/>
      <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>

    <Grid.ColumnDefinitions>
      <ColumnDefinition/>
      <ColumnDefinition/>
    </Grid.ColumnDefinitions>

    <!-- Bind ItemsSource to source using explicit object
         reference instead of DataContext -->
    <ComboBox x:Name="comboBox1"
              ItemsSource="{Binding DataList, ElementName=mainWindow1}"
              DisplayMemberPath="Name"/>

    <!-- Now, edit fields will automatically track selected item -->
    <TextBlock Text="Name:" TextAlignment="Right" Grid.Row="1"/>
    <TextBlock Text="Value:" TextAlignment="Right" Grid.Row="2"/>

    <TextBox Text="{Binding Name}" Grid.Row="1" Grid.Column="1"/>
    <TextBox Text="{Binding Value}" Grid.Row="2" Grid.Column="1"/>
  </Grid>
</Window>

C#:

public partial class MainWindow : Window
{
    public List<Data> DataList { get; private set; }

    public MainWindow()
    {
        DataList = new List<Data>();
        DataList.Add(new Data { Name = "Data item 1", Value = "value 1" });
        DataList.Add(new Data { Name = "Data item 2", Value = "value 2" });
        DataList.Add(new Data { Name = "Data item 3", Value = "value 3" });
        InitializeComponent();
    }
}

public class Data
{
    public string Name { get; set; }
    public string Value { get; set; }
}

I just wrote it from scratch rather than trying to incorporate your incomplete example, as your example is missing too many things to allow it to be practical to try to complete. I also left out binding-friendly features like ObservableCollection<T> and INotifyPropertyChanged implementations. I trust that even so, you can see from the example what I mean, and can apply the same technique to your own code appropriately.

Peter Duniho
  • 68,759
  • 7
  • 102
  • 136