简体   繁体   English

DataGrid显示为空MVVM Wpf

[英]DataGrid display is empty MVVM Wpf

The problem: the DataGrid display is empty, however I have infos, and my DataGrid received the information but still empty! 问题:DataGrid显示为空,但是我有信息,我的DataGrid收到信息但仍然是空的!

My XAML: 我的XAML:

<DataGrid x:Name="dataGrid" Grid.Row="1" ItemsSource="{Binding ViewList}" 
          CanUserAddRows="False" AlternationCount="2"
          AlternatingRowBackground="Blue">
  <DataGrid.Columns>
    <DataGridTextColumn Header="View" Binding="{Binding id}"
                        Width="2*" IsReadOnly="True" />
    <DataGridTemplateColumn Header="Is Enabled" Width="Auto">
      <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
          <CheckBox IsChecked="{Binding isEnabled, Mode=TwoWay,
                        UpdateSourceTrigger=PropertyChanged}"/>
        </DataTemplate>
      </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>                
  </DataGrid.Columns>
</DataGrid>

My ViewModel: 我的ViewModel:

public ConfigRoleModel()
{
    _viewList = new ObservableCollection<ViewList>(WCFclient.getListOfViews(1));
}

private ObservableCollection<ViewList> _viewList;
public ObservableCollection<ViewList> ViewList
{
    get { return _viewList; }
    set
    {
        _viewList = value;
        OnPropertyChanged("ViewList");
    }
}  

ViewList class: ViewList类:

public class ViewList
{
    public int id;    
    public string description;
    public string code;
}

This is the result: 这是结果: 在此输入图像描述

How can I fix it ? 我该如何解决?

By looking at your code: 通过查看您的代码:

  1. You should define public property in your ViewList class for binding to work. 您应该在ViewList类中定义公共属性以使绑定工作。

  2. set Datacontext to your viewModel. 将Datacontext设置为viewModel。

  3. No isEnabled property in your DataContext DataContext中没有isEnabled属性

Your ViewList Class should look like this: 您的ViewList类应如下所示:

public class ViewList 
{
    public int Id { get; set; }
    public bool IsEnabled { get; set; }
    ...
}

and your Xaml: 和你的Xaml:

<DataGrid x:Name="dataGrid" Grid.Row="1"  ItemsSource="{Binding ViewList}" 
           CanUserAddRows="False" AlternationCount="2" AlternatingRowBackground="Blue" >
    <DataGrid.Columns>
        <DataGridTextColumn Header="View" Binding="{Binding Id}" Width="2*" IsReadOnly="True" />

        <DataGridTemplateColumn Header="Is Enabled" Width="Auto">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <CheckBox IsChecked="{Binding IsEnabled , Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>                
    </DataGrid.Columns>
</DataGrid>

And in your view code behind or in your xaml itself: 在您的视图代码中或在您的xaml本身中:

  • Set your DataContext to your ViewModel 将DataContext设置为ViewModel

Fields are not valid targets for WPF bindings. 字段不是WPF绑定的有效目标。 You should use a property instead. 您应该使用属性。

public class ViewList {
    public int Id { get; set; }
    public string Description { get; set; }
    public string Code { get; set; }
    public bool IsEnabled { get; set; }
}

Make sure that your View List class implements INotifyPropertyChanged 确保View List类实现了INotifyPropertyChanged

public class ViewList : INotifyPropertyChanged
{
    private int _id;
    public int id
    {
        get { return _id; }
        set
        {
            _id = value;
            OnPropertyChanged(new PropertyChangedEventArgs("id"));
        }
    }

    private string _description;
    public string description
    {
        get { return _description; }
        set
        {
            if((value as string) != null)
            {
                _description = value;
                OnPropertyChanged(new PropertyChangedEventArgs("description"));
            }
        }
    }

    private string _code;
    public string code
    {
        get { return _code; }
        set
        {
            _code = value;
            OnPropertyChanged(new PropertyChangedEventArgs("code"));
        }
    }

    private bool _isEnabled;
    public bool isEnabled
    {
        get { return _isEnabled; }
        set
        {
            _isEnabled = value;
            OnPropertyChanged(new PropertyChangedEventArgs("isEnabled"));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, e);
        }
    }
}

Your ViewModel does not need to implement INotifyPropertyChanged if you are just wanting to display data from the ObservableCollection. 如果您只想显示ObservableCollection中的数据,则ViewModel不需要实现INotifyPropertyChanged。 Here is my ViewModel: 这是我的ViewModel:

public class MainWindowVM
{
    private ObservableCollection<ViewList> _MyList;
    public ObservableCollection<ViewList> MyList
    {
        get { return _MyList; }
        set
        {
            if(value != null)
            {
                _MyList = value;
            }
        }
    }

    public MainWindowVM()
    {
        _MyList = new ObservableCollection<WpfDataGridTest.ViewList>();

        _MyList.Add(new WpfDataGridTest.ViewList() { id = 1, code = "C101", description = "test1", isEnabled = true });
        _MyList.Add(new WpfDataGridTest.ViewList() { id = 2, code = "C102", description = "test2", isEnabled = false });
        _MyList.Add(new WpfDataGridTest.ViewList() { id = 3, code = "C103", description = "test3", isEnabled = true });
    }
}

Here is my Window's XAML 这是我的Window的XAML

<Window x:Class="WpfDataGridTest.MainWindow"
        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:WpfDataGridTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525"
        DataContext="{StaticResource MainWindowVM}">
    <Grid>
        <DataGrid x:Name="dataGrid" HorizontalAlignment="Left" Margin="33,34,0,0" VerticalAlignment="Top" Height="236" Width="444" 
                  CanUserAddRows="False" AlternationCount="2" AlternatingRowBackground="Blue"  AutoGenerateColumns="False" IsSynchronizedWithCurrentItem="True"
                  ItemsSource="{Binding MyList}">
            <DataGrid.Columns>
                <DataGridTextColumn Header="View" Binding="{Binding id}" Width="2*" IsReadOnly="True" />

                <DataGridTemplateColumn Header="Is Enabled" Width="Auto">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <CheckBox IsChecked="{Binding isEnabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>

    <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="44,10,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"
             Text="{Binding Path=CurrentItem.description, ElementName=dataGrid}"/>
</Window>

This example shows the 3 rows as expected for me using VS 2015. as you can see here: 这个例子显示了我使用VS 2015预期的3行。你可以在这里看到:

WPFDataGridTest应用程序捕获 Note: I renamed your ViewList member of the ViewModel to MyList because I don't like having a member be the same name of a class as it can make things confusing. 注意:我将ViewModel的ViewList成员重命名为MyList,因为我不喜欢让一个成员与一个类的名称相同,因为它会让事情变得混乱。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM