【问题标题】:WPF: How to bind the result of an OpenFileDialog to a TextBox.Text, which is already boundWPF:如何将 OpenFileDialog 的结果绑定到已绑定的 TextBox.Text
【发布时间】:2015-11-25 04:46:23
【问题描述】:

我有一个 ListBox,它绑定到一个对象列表,在这个 ListBox 的 DataTemplate 中我有一个 TextBox,它绑定到这个对象的一个​​属性。现在我在这个 DataTemplate 中也有一个按钮,它打开了一个 OpenFileDialog。我想把这个OpenFileDialog的结果绑定到TextBox.Text,所以结果显示在TextBox中,绑定到这个TextBox的对象的值变成了result。

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>

背后的代码:

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

列表中绑定到ListBox的对象,结构如下:

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

【问题讨论】:

  • 你试过txtPath.Text = fileDialog.FileName; 吗?
  • 是的,但是如果我这样做了,我会覆盖绑定并且不会更改值 Prop2

标签: c# wpf xaml data-binding


【解决方案1】:

你的类应该实现INofifyPropertyChanged,你的集合应该实现IListChanged接口(比如ObservableCollectionBindingList

如果是这种情况并且您更新了属性,则绑定控件将更新其内容。

有很多方法可以实现 INotifyPropertyChanged。最快的解决方案是这样的:

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

}

【讨论】:

    【解决方案2】:

    如果Textbox 已经绑定到prop1,最好只更改prop1 值以更改您的文本框文本。比如

    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.
        }
    }
    

    因此文本框文本将被更改。

    【讨论】:

    • 抱歉,这里说的不够清楚,但Property Prop1 是绑定到ListBox 的Object 的一部分,为了更好的解释,我在List 中添加了Item 的结构跨度>
    • @steffengerdes 那么最好将 item.prop1 设置为文件名。
    • var item = (Item)((FrameworkElement)sender).DataContext;
    【解决方案3】:

    您可以使用基本功能设置属性值:

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

    我本可以发誓 txtPath.Text = fileDialog.FileName; 会为你做这件事,但我现在没有编译器来测试它。

    【讨论】:

    • 同样的事情,当我设置值时,我会覆盖 Binding 并且不会更改 Prop2 的值
    猜你喜欢
    • 2014-12-08
    • 2019-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-20
    • 2010-10-02
    相关资源
    最近更新 更多