绑定到一个ObservableCollection<string>

3

我希望做的事情非常简单:我想在一个ItemsControl中显示一个ObservableCollection。我还希望用户能够编辑ObservableCollection中的字符串。

我的视图模型非常简单:

public class MainViewModel : ViewModelBase
{
    public ObservableCollection<string> Values { get; set; }

    public MainViewModel()
    {
        Values = new ObservableCollection<string> { "foo", "bar" };
    }
}

在我的看法中,我为我的ItemsControl定义了一个DataTemplate来显示每个项内的文本框,这里没有问题:

<ItemsControl ItemsSource="{Binding Values}">
            <ItemsControl.ItemTemplate>
                <DataTemplate DataType="{x:Type sys:String}">
                    <TextBox Text="{Binding Path=., UpdateSourceTrigger=PropertyChanged}" />
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

所有的东西似乎都很顺利,我可以在视图中看到我的ObservableCollection的内容。然而,当我编辑文本框中的文本时,我的ObservableCollection没有被更新,值仍然是相同的。

我发现唯一的解决方法是创建一个类:

public class StringWrapper
{
    public string Value { get; set; }
}

然后,我将我的ObservableCollection的类型更改为ObservableCollection<StringWrapper> ,并在我的DataTemplate中,将TextBox的Text属性绑定到Value。这样做是有效的,但不够美观。

所以我的问题是,有没有一种方法可以将ObservableCollection绑定到ItemsControl并能够更新值?


3
<TextBox Text="{Binding Path=., UpdateSourceTrigger=PropertyChanged}" />这段代码中,String类未实现INotifyPropertyChanged接口。请将其替换为<TextBox Text="{Binding}" /> - Aron
@Aron:为什么你要在评论里回答? :/ - thomasb
3个回答

3

除非直接由列表控件处理,否则我怀疑没有办法做到这一点。您的ItemsControl中的模板项只能访问string实例,而不能访问实际集合。由于string是不可变的,所以这是一个死路,无法追溯更改的源头。


我不知道在C#中string是不可变的。现在我更好地理解了为什么使用StringBuilder而不是直接修改string是一个好习惯。那我就坚持使用这种丑陋的方式,谢谢! - MisterBait

1

您的属性值需要实现INotifyPropertyChanged接口,只有绑定Values属性后才能正常工作。


0

我认为将绑定设置为自身即可完成工作,不要忘记将其设置为双向绑定。

TextBox Text="{Binding}",Mode=TwoWay


1
双向模式是默认设置。 - alan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接