【问题标题】:Databind between one textbox and an ObservableCollection of child objects一个文本框和一个 ObservableCollection 子对象之间的数据绑定
【发布时间】:2013-10-24 14:09:49
【问题描述】:

我有以下情况:

class A { myCollection = new ObservableCollection<B>(); 
....
 myCollection.Add(new B1());
 myCollection.Add(new B2());
....
for each (B b in myCollection)
   b.DoWork();

}

其中 B 是具有一组专门子类的抽象类(比如 B1、B2...)。 B 具有“State”属性,以及被他的子类覆盖的 DoWork 方法。 在每个专门的 DoWork 中,状态属性的更改都不同。

  abstract class B { 
        string _state = null;
        public string State
        {
            get
            {
                return _state;
            }
            set
            {
                _state = value;
                OnPropertyChanged( "State" );
            }

        public bool DoWork();
   }

 class B1:B { 
    override public bool DoWork()
            {
                State = "Press button XXXX to do something";
                .....
                return true;
            }
    }

class B2:B { 
        override public bool DoWork()
                {
                    State = "Press button YYYY to do something else";
                    ....
                    return true;
                }
        }

在我的xaml文件中datacontext是A,我不知道怎么设置Binding:

<Window.DataContext>
    <!-- Declaratively create an instance of A-->
    <VW:A />
</Window.DataContext>
....
<TextBox Text="{Binding Path=????State????}" />

我想在调用时用数据绑定改变TextBox文本

for each (B b in myCollection)
       b.DoWork();

我尝试了几种绑定指令,但都不起作用......

感谢谢里根的解决方案:

如果您想显示集合中所有对象的所有属性togheter,则 SHRIGAN 解决方案很好,但是

我实际上想要实现的是拥有一个对象集合,所有这些对象都会更新 same 视觉组件。集合中的对象代表状态,因此始终只有一个处于活动状态。 所以我所做的是编辑 A 类:

class A { myCollection = new ObservableCollection<B>(); 
....
 private B temp;
 myCollection.Add(new B1());
 myCollection.Add(new B2());
....
for each (B b in myCollection) {
   temp = b
   temp.DoWork();
}

public B TEMP
    {
        get
        {
            return temp;
        }

        set
        {
            temp = value;
            OnPropertyChanged( "TEMP" );
        }
    }

在 xaml 中

<TextBox Text="{Binding Path=TEMP.State}"/>

}

【问题讨论】:

    标签: wpf c#-4.0 data-binding observablecollection children


    【解决方案1】:

    基本上,您需要A 类中的public 集合属性,并且它还需要实现INotifyPropertyChanged 接口。然后你需要Bind那个集合属性到一个集合控件:

    <ListBox ItemsSource="{Binding CollectionProperty}">
        ...
    </ListBox>
    

    然后您可以在ItemTemplate 中设置每个项目的外观:

    <ListBox ItemsSource="{Binding CollectionProperty}">
        <ListBox.ItemTemplate>
            <DataTemplate DataType="{x:Type YourXmlNamespace:B}">
                <TextBox Text="{Binding Path=State}" />
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    

    我感觉在 XAML 中使用基类是行不通的,但我可能是错的。您可能必须将DataType 属性设置为B1B2。这可能可能不适用于A的实例...我目前无法测试。


    更新>>>

    听起来您的收藏中有一个空项目正在为其生成ItemTemplateTextBox)。但是,您实际上必须使用集合控件来显示集合中的项目...如果您只想显示一个项目,您应该能够使用索引器Binding.Path语法:

    <TextBox Text="{Binding CollectionProperty[0].State}" />
    

    【讨论】:

    • 给出编译错误,所以我使用了 ,但绑定仍然不起作用。
    • 您遇到了什么错误?希望您了解adding XML Namespaces,并且您需要为我在示例中使用的YourXmlNamespace 前缀添加一个。
    • 好的,我可以定义xmlns:custom="clr-namespace:mynamespace.BSubNamespace"&lt;DataTemplate DataType="{x:Type custom:B}"&gt;。它也可以在不声明 xmlns:custom 和使用&lt;DataTemplate DataType="this:B"&gt; 的情况下工作。核心概念是我首先需要绑定集合以绑定到集合中包含的对象内的属性。
    • 但现在我有一个视觉问题:似乎将文本框放在列表框内会在正确的文本框下方增加 1 个文本框......有什么想法吗?
    • 我明白了,listbox 会自动为 mycollection 中的每个对象创建一个文本框。我在公开帖子中发布了我的最终解决方案。无论如何你能解释一下使用&lt;DataTemplate DataType="{x:Type custom:B}"&gt;&lt;DataTemplate DataType="this:B"&gt;有什么区别吗?
    猜你喜欢
    • 2012-10-23
    • 1970-01-01
    • 1970-01-01
    • 2011-06-27
    • 2014-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多