简体   繁体   中英

WPF: How to bind the result of an OpenFileDialog to a TextBox.Text, which is already bound

I have a ListBox, which is bound to a list of objects and in the DataTemplate of this ListBox I have a TextBox, which is bound to a Property of this objects. Now I have a Button in this DataTemplate, too, that opens an OpenFileDialog. I want to bind the result of this OpenFileDialog to the TextBox.Text, so the result is shown in the TextBox and the value of the object, which is bound to this TextBox changes to result.

The Xaml:

<ListBox Name="MyList">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <DockPanel>
                <Button Name="btnOpen" Click="BtnOpen_OnClick"/>
                <TextBox Name="txtPath" Text="{Binding Path=Prop2, Mode=TwoWay}"/>
            </DockPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

The Code Behind:

private void BtnOpen_OnClick(object sender, RoutedEventArgs e)
{
    OpenFileDialog fileDialog = new OpenFileDialog();
    fileDialog.Multiselect = false;

    dynamic result = fileDialog.ShowDialog();

    if (result == true) 
    {
        //bind to TextBox textproperty here
    }
}

The objects in the list that is bound to the ListBox, are structured as follows:

public class Item
{
    public string Prop1 { get; set; }
    public string Prop2 { get; set; }
    public bool Prop3 { get; set; }

    public Item(string prop1)
    {
        this.Prop1 = prop1;
    }

    public Item(string prop1, string prop2)
    {
        this.Prop1 = prop1;
        this.Prop2 = prop2;
    }

    public Item(string prop1, string prop2, bool prop3)
    {
        this.Prop1 = prop1;
        this.Prop2 = prop2;
        this.Prop3 = prop3;
    }
}

If the Textbox has already bound to prop1 maybe it's better to just change prop1 value in order to change your textbox text. such as

private void BtnOpen_OnClick(object sender, RoutedEventArgs e)
{
    OpenFileDialog fileDialog = new OpenFileDialog();
    fileDialog.Multiselect = false;

    dynamic result = fileDialog.ShowDialog();

    if (result == true) 
    {
        prop1=fileDialog.FileName; // set prop1 in the appropriate way.
    }
}

Consequently the textbox text will be changed.

Your class should implement INofifyPropertyChanged and your collection should implement IListChanged interface (like ObservableCollection or BindingList

If that's the case and you update your property the bound control will update its content.

There are many ways to implement INotifyPropertyChanged. The quickest solution is this:

public class Item : INotifyPropertyChanged
{
    private string prop2;
    public string Prop2 
    { 
         get { return prop2; }
         set { prop2 =  value; OnPropertyChanged("Prop2"); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        var eh = this.PropertyChanged;
        if (eh != null)
            eh(this, new PropertyChangedEventArgs(propertyName));
    }

}

You can set a property value by using the base functionality:

if (result == true) 
{
    txtName.SetValue(TextBox.TextProperty, fileDialog.FileName); 
}

I could have sworn txtPath.Text = fileDialog.FileName; would do this for you, but I don't have a compiler to test it right now.

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