如何使用双向模式将Listview的选定项绑定到Textbox?

6
我对WPF非常陌生,正在测试一些我想在即将开发的应用程序中使用的东西。我有一个2行的ListView(绑定到一个文本框),其中包含Scott Guthrie和Jon Skeet的名称。我尝试选择"Scott Guthrie"并将其填充到文本框中。我希望能够编辑文本并切换,然后让ListView更新。

好的,下次我只会翻译文本内容。 - Gishu
请分享你的代码,Nick U. - Eric
2个回答

38

哇,你的内容真的很复杂。

这可以通过非常简单的方式来实现。您需要一个模型来表示程序员,一个视图模型来保存程序员列表,并使用简单的绑定来处理其余部分。

该模型:

public sealed class Programmer
{
    public string Name { get; set; }
}

非常简单。一个代表程序员姓名的对象。我们必须将名字封装在对象中,因为在.NET中字符串是不可变的。如果你试图绑定一个字符串列表中的单个字符串,更改将无法传播。
程序员集合保存在ViewModel中。在这种情况下,我称之为ViewModel,因为我没有想象力。这个视图模型包含视图绑定的所有内容。在这种情况下,它是程序员列表。
public sealed class ViewModel
{
    public ObservableCollection<Programmer> Programmers { get; private set; }

    public ViewModel()
    {
        Programmers = new ObservableCollection<Programmer>();
    }
}

ViewModel被设置为视图的DataContext。 DataContext沿着可视树向下传递,我们可以在任何时候绑定它。

public MainWindow()
{
    var vm = new ViewModel();
    vm.Programmers.Add(new Programmer { Name = "Jon Skeet" });
    vm.Programmers.Add(new Programmer { Name = "Scott Guthrie" });
    DataContext = vm;
    InitializeComponent();
}

您可以按照任何方式设置DataContext;我在这里是为了简单起见。

在UI中,我只需将ListView绑定到ViewModel中Programmers列表(除非另有说明,否则DataContext是绑定路径的根)。然后,我将TextBox绑定到ListBox的SelectedItem。您从列表中选择一个程序员,它就成为SelectedItem,然后我可以更改其名称。

<Window
    x:Class="Programmers.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:t="clr-namespace:Programmers"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <ListBox
            x:Name="list"
            ItemsSource="{Binding Programmers}"
            DisplayMemberPath="Name" />
        <TextBox
            Grid.Column="1"
            VerticalAlignment="Top"
            Text="{Binding SelectedItem.Name, ElementName=list}" />
    </Grid>
</Window>

一旦你掌握了技巧,这就很简单了。


3
好的,似乎知道是解决问题的一半。谢谢!就是这样! - Nick U
4
@nick GI Joooooeeeeeeeeeeeeeeeee! - user1228
+1。谢谢,兄弟,真的帮了我!不过我用的是list.ItemSource = vm而不是DataContext = vm。我觉得当我有多个列表时应该这样做,但因为我对WPF还不熟悉,所以不太确定。 - radbyx
1
小提示,由于OP询问的是ListView而此解决方案适用于ListBoxListViewListBox的子类,因此此代码对两者都有效。 - cod3monk3y

5

这个方法可以使用(但是你需要验证文本框,因为你可以输入任何文本..下拉菜单可能是更好的选择)。

视图:

<TabItem x:Name="RightTabPage" Header="RightModel"  DataContext="{Binding Right}">
                    <StackPanel>
                        <TextBox Text="{Binding SelectedGuru}"/>
                        <ListView SelectedItem="{Binding SelectedGuru}" ItemsSource="{Binding Gurus}"/>
                    </StackPanel>
                </TabItem>

ViewModel:

public class RightViewModel
    {
        public RightViewModel()
        {
            Gurus = new[] {"Scott Guthrie", "Jon Skeet"};
            SelectedGuru = Gurus.First();
        }

        public string SelectedGuru { get; set; }
        public IEnumerable<string> Gurus{ get; set; }
    }

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