C#,WPF,将List<string>绑定到DataGrid

7

我在将List绑定到DataGrid时遇到了麻烦。应该尽可能简单。我是WPF的新手,这是为了个人学习。

我有一个视图(Editor),一个视图模型(VMText)和一个数据(JustText)类。

到目前为止我的代码:

JustText.cs

namespace Model
{
    public class Text
    {
        private string _code;
        public string Code
        {
            get { return _code;  }
            set { _code = value; }
        }

        public Text()
        {
            _code = "Hello World!\nHow you doin'?";
        }
    } 
}

VMText.cs

namespace ViewModel
{
    public class VMText
    {    
        private Model.Text _code;

        public List<string> Code
        {            
            get { return new List<string>(_code.Code.Split('\n'));        }
            set { _code.Code = System.String.Join("\n", value.ToArray()); }
        }

        private View.Editor editor;

        public VMText(View.Editor editor)
        {
            _code = new Model.Text();
            this.editor = editor; 
        }
    }
}

Editor.xaml

<Window x:Class="View.Editor"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:View"
        mc:Ignorable="d"
        Title="Editor" Height="240.024" Width="269.895">
    <Grid Background="#FF292929" Margin="0,0,-6.8,0.4">
        <DataGrid x:Name="dataGrid" 
                  HorizontalAlignment="Left" 
                  Margin="0,0,0,0" 
                  VerticalAlignment="Top"
                  Width="200pt"
                  Height="100pt"
                  DataContext="{Binding vmText}">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding Code, UpdateSourceTrigger=PropertyChanged}" Foreground="Black" Width="60" Header="Test" IsReadOnly="false" />
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

Editor.xaml.cs

namespace View
{
    public partial class Editor : Window
    {
        private ViewModel.VMText vmText;

        #region Constructor

        public Editor()
        {
            InitializeComponent();

            vmText = new ViewModel.VMText(this);
            DataContext = vmText;
        }

        #endregion
    }
}

我只想在DataGrid中的一列中显示在VMText中创建的List。

2
看起来你需要在DataGrid上设置ItemsSource属性。 - momar
1
public List<string> Code {...} is you collection of data for DataGrid, so Bind it in <DataGrid x:Name="dataGrid" ... ItemsSource="{Binding Code}"> - Dawid Wekwejt
1
  1. ItemsSource="{Binding Code}"。不要在网格上设置DataContext;它会从视图中继承。
  2. 那个ItemsSource绑定不会替换Code;它将编辑Code中的项目,这在你编写的方式中是不可能的。使用你拥有的视图模型,你只能显示Code中的项目。所以Code需要改变:它必须是一个可观察的类集合,该类具有网格可以编辑的属性。
- 15ee8f99-57ff-4f92-890c-b56153
3个回答

16

我想你只是想在DataGrid中显示视图模型的Code source collection属性中的字符串。

然后,你应该将DataGrid的ItemsSource属性绑定到视图模型的Code source属性,然后将DataGridTextColumn绑定到Code列表中的字符串本身。你只需要稍微修改一下视图的XAML标记就能看到字符串了。试试这个:

<DataGrid x:Name="dataGrid" 
              HorizontalAlignment="Left" 
              Margin="0,0,0,0" 
              VerticalAlignment="Top"
              Width="200pt"
              Height="100pt"
              ItemsSource="{Binding Code}"
              AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding}" 
                                Foreground="Black" Width="60" Header="Test" IsReadOnly="false" />
    </DataGrid.Columns>
</DataGrid>


谢谢,这个方法有效。我也尝试了使用 Binding="{Binding Path =.}",它也有效。但这还是一种“试错”的方式。我需要弄清楚绑定的概念。 - dipa2016
1
{Binding} 是 {Binding Path=.} 的缩写:https://msdn.microsoft.com/zh-cn/library/ms750413(v=vs.110).aspx。请记得接受答案并投票支持有用的回答。 - mm8
谢谢,我不明白为什么会多出一列名为“Length”的列……这是由于DataGrid上缺少“AutoGenerateColumns = False”属性引起的。 - Ishikawa

3
你应该实现 INotifyPropertyChanged 来通知绑定属性已更改。对于集合,请使用ObservableCollection 而不是 List

1
将VMText.Code绑定到DataGrid ItemSource。当您在代码后台执行此操作时,不需要在视图中初始化DataGrid DataContract。
ViewModel
namespace ViewModel
{
    public class VMText : INotifyPropertyChanged
    {
        public VMText(View.Editor editor)
        {
            _code = new Model.Text();
            this.editor = editor; 
        }

        public List<string> Code
        {            
            get
            {
                return new List<string>(_code.Code.Split('\n'));
            }
            set
            {
                _code.Code = System.String.Join("\n", value.ToArray());
                NotifyPropertyChanged("Code");
            }
        }

        private void NotifyPropertyChanged(String propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private Model.Text _code;

        private View.Editor editor;
    }
}

视图

<Window x:Class="View.Editor"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:View"
    mc:Ignorable="d"
    Title="Editor" Height="240.024" Width="269.895">
<Grid Background="#FF292929" Margin="0,0,-6.8,0.4">
    <DataGrid x:Name="dataGrid" 
              HorizontalAlignment="Left" 
              Margin="0,0,0,0" 
              VerticalAlignment="Top"
              Width="200pt"
              Height="100pt"
              ItemsSource="{Binding Code}>
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Code"
                                Foreground="Black" Width="60"
                                Header="Test"
                                IsReadOnly="false" />
        </DataGrid.Columns>
    </DataGrid>
</Grid>

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