简体   繁体   中英

DataBinding Textbox.Text to a specific element of a string array

Delving into the wonderful world of .NET databinding. I have a textbox whose text property I want to bind to a specific element of a string array in another object. (The form contains a combobox that selects the index of the element).

In other words, I'd like to do something like this:

textBoxFictionShort.DataBindings.Add(
                new Binding("Text", m_Scenario, "Fiction[int32.Parse(comboBoxSelector.Text)]"));

where m_Scenario contains the

public string[] Fiction { get; set; }

property that I source from. Obviously the Binding above won't retrieve my item. AFAIK I can't create properties that accept parameters. What's the elegant/correct solution for this when using databinding? I can think of several ugly-seeming workarounds (ie a string property in m_Scenario that references the array string I'm binding to, and a public function that updates the string property on the combobox SelectedIndexChanged event).

This is an excellent place to have a View Model . Here's another ViewModel link

What I would do is have the following in the ViewModel (that gets bound to by components on the view)

an IObservable property bound to the items source of the combo box, that you add/remove to depending on the size of the array

a int property for the selected index bound to the SelectedElement of the combo box. You would have to do the conversion from string to int when this property is being set.

a string property that is bound to the textbox.text (you could likely use a label here, by the by) that is updated each time the aforementioned int property for the selected index is changed.

If this at all confusing I can build up some pseudo code, but those three properties should work and get you what you want.

Edit - To add some code:

public class YourViewModel : DependencyObject {
    public string[] FictionArray {get; private set;}

    public IObservable<string> AvailableIndices;

    public static readonly DependencyProperty SelectedIndexProperty=
      DependencyProperty.Register("SelectedIndex", typeof(string), typeof(YourViewModel), new PropertyMetadata((s,e) => {
        var viewModel = (YourViewModel) s;
        var index = Convert.ToInt32(e.NewValue);
        if (index >= 0 && index < viewModel.FictionArray.Length)
            viewModel.TextBoxText=FictionArray[index];
      }));

    public bool SelectedIndex {
      get { return (bool)GetValue(SelectedIndexProperty); }
      set { SetValue(SelectedIndexProperty, value); }
    }

    public static readonly DependencyProperty TextBoxTextProperty=
      DependencyProperty.Register("TextBoxText", typeof(string), typeof(YourViewModel));

    public bool TextBoxText {
      get { return (bool)GetValue(TextBoxTextProperty); }
      set { SetValue(TextBoxTextProperty, value); }
    }

    public YourViewModel(string[] fictionArray) {
        FictionArray = fictionArray;
        for (int i = 0; i < FictionArray.Length; i++){
            AvailableIndices.Add(i.ToString()));
        }
    }
}

This isn't perfect, but it should give you some idea how you could create a viewmodel with properties that you could bind to. So in your xaml you'd have something like:

<ComboBox ItemSource="{Binding AvailableIndices}" SelectedItem="{Binding SelectedIndex}"/>

<TextBox Text="{Binding TextBoxText}"/>

I think you are in WinForms (not WPF), in this case you could just bind directly to the ComboBox's SelectedValue property...

comboBox1.DataSource = m_Scenario.Fiction;
textBoxFictionShort.DataBindings.Add(new Binding("Text", comboBox1, "SelectedValue"));

Add BindingSource

        ...
        bindingSource1.DataSource = m_Scenario.Fiction
            .Select((x, i) => new {Key = i + 1, Value = x})
            .ToDictionary(x => x.Key, x => x.Value);
        comboBox1.DisplayMember = "Key";
        comboBox1.DataSource = bindingSource1;
        textBox1.DataBindings.Add("Text", bindingSource1, "Value");
      }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM