wpf绑定

时间:2017-04-10 04:27:20

标签: wpf mvvm data-binding datagrid

最后

  

我发现财产"项目"也许重用SelectedItem = {Binding   Item},所以它总是异常。

我有一个DataGrid,包括扩展器。

编辑 当我想使用SelectedItem时,我得到" NullReferenceException"。

当我想要做某些事情时,比如UnSelectAll或Collection.Remove SelectedItem,我得到" NullReferenceException"。

示例名为UnSelectAll stacktrace

---------------------------
   於 MS.Internal.Data.PropertyPathWorker.DetermineWhetherDBNullIsValid(Object item)

   於 MS.Internal.Data.PropertyPathWorker.DetermineWhetherDBNullIsValid()

   於 MS.Internal.Data.PropertyPathWorker.get_IsDBNullValidForUpdate()

   於 MS.Internal.Data.ClrBindingWorker.get_IsDBNullValidForUpdate()

   於 System.Windows.Data.BindingExpression.ConvertProposedValue(Object value)

   於 System.Windows.Data.BindingExpressionBase.UpdateValue()

   於 System.Windows.Data.BindingExpression.UpdateOverride()

   於 System.Windows.Data.BindingExpressionBase.Update()

   於 System.Windows.Data.BindingExpressionBase.ProcessDirty()

   於 System.Windows.Data.BindingExpressionBase.Dirty()

   於 System.Windows.Data.BindingExpressionBase.SetValue(DependencyObject d, DependencyProperty dp, Object value)

   於 System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)

   於 System.Windows.DependencyObject.SetCurrentValueInternal(DependencyProperty dp, Object value)

   於 System.Windows.Controls.Primitives.Selector.UpdatePublicSelectionProperties()

   於 System.Windows.Controls.Primitives.Selector.SelectionChanger.End()

   於 System.Windows.Controls.Primitives.Selector.UnselectAllImpl()

   於 System.Windows.Controls.DataGrid.UnselectAllCells()

   於 SList.Expander_Click(Object sender, RoutedEventArgs e) 於 D:\SList.xaml.cs: 行 123, System.NullReferenceException: 並未將物件參考設定為物件的執行個體。

   於 MS.Internal.Data.PropertyPathWorker.DetermineWhetherDBNullIsValid(Object item)

   於 MS.Internal.Data.PropertyPathWorker.DetermineWhetherDBNullIsValid()

   於 MS.Internal.Data.PropertyPathWorker.get_IsDBNullValidForUpdate()

   於 MS.Internal.Data.ClrBindingWorker.get_IsDBNullValidForUpdate()

   於 System.Windows.Data.BindingExpression.ConvertProposedValue(Object value)

   於 System.Windows.Data.BindingExpressionBase.UpdateValue()

   於 System.Windows.Data.BindingExpression.UpdateOverride()

   於 System.Windows.Data.BindingExpressionBase.Update()

   於 System.Windows.Data.BindingExpressionBase.ProcessDirty()

   於 System.Windows.Data.BindingExpressionBase.Dirty()

   於 System.Windows.Data.BindingExpressionBase.SetValue(DependencyObject d, DependencyProperty dp, Object value)

   於 System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)

   於 System.Windows.DependencyObject.SetCurrentValueInternal(DependencyProperty dp, Object value)

   於 System.Windows.Controls.Primitives.Selector.UpdatePublicSelectionProperties()

   於 System.Windows.Controls.Primitives.Selector.SelectionChanger.End()

   於 System.Windows.Controls.Primitives.Selector.UnselectAllImpl()

   於 System.Windows.Controls.DataGrid.UnselectAllCells()

   於 SList.Expander_Click(Object sender, RoutedEventArgs e) 於 D:\SList.xaml.cs: 行 123
---------------------------

但SelectedIndex运作良好。

我不知道发生了什么,但我需要绑定SelectedItem。

请帮忙!

我的ViewModel

public class TestVM : INotifyPropertyChanged
{
    private int _index;
    public int Index
    {
        get
        {
            return _index;
        }
        set
        {
            _index = value;
            RaisePropertyChanged("Index");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void RaisePropertyChanged(String propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    private User _item;
    public User Item
    {
        get
        {
            return _item;
        }
        set
        {
            _item = value;
            RaisePropertyChanged("Item");
        }
    }

    ObservableCollection<User> _collection;
    public ObservableCollection<User> Collection
    {
        get
        {
            return _collection;
        }
        private set
        {
            _collection = value;
            RaisePropertyChanged("Collection");
        }
    }

    ListCollectionView _groupView;
    public ListCollectionView GroupView
    {
        get
        {
            return _groupView;
        }
        private set
        {
            _groupView = value;
            RaisePropertyChanged("GroupView");
        }
    }

    public TestVM()
    {
        Collection = new ObservableCollection<User>();
        Collection.Add(new User() { Name = "John Doe1", Age = 10, group = "Group 1" });
        Collection.Add(new User() { Name = "Jane Doe2", Age = 20, group = "Group 1" });

        Collection.Add(new User() { Name = "Sammy Doe", Age = 30, group = "Group 2" });
        Collection.Add(new User() { Name = "Sammy Doe1", Age = 40, group = "Group 2" });
        Collection.Add(new User() { Name = "Sammy Doe2", Age = 50, group = "Group 2" });

        Collection.Add(new User() { Name = "Sammy Doe3", Age = 60, group = "Group 3" });
        Collection.Add(new User() { Name = "Sammy Doe4", Age = 70, group = "Group 3" });
        Collection.Add(new User() { Name = "Sammy Doe5", Age = 80, group = "Group 3" });

        GroupView = new ListCollectionView(Collection);
        GroupView.GroupDescriptions.Add(new PropertyGroupDescription("group"));
    }
}

public class User
{
    public string Name { set; get; }
    public int Age { set; get; }

    public string group { get; set; }
}

XAML

<DataGrid Name="dg" ItemsSource="{Binding Collection}" SelectedIndex="{Binding Index, Mode=TwoWay}" SelectedItem="{Binding Item, Mode=TwoWay}"/>

3 个答案:

答案 0 :(得分:0)

==&gt;中的错误SelectedIndex =&#34; {Binding Index}&#34; 更改为==&gt; SelectedIndex =&#34; {Binding Index,Mode = TwoWay}&#34;

<DataGrid Name="dg" ItemsSource="{Binding GroupView}" SelectedIndex="{Binding Index,Mode=TwoWay}" SelectedItem="{Binding Item,Mode=TwoWay}" SelectionChanged="SelectionChanged"
          AutoGenerateColumns="False" CanUserAddRows="False" 
          CanUserResizeColumns="False" CanUserResizeRows="False"
          CanUserSortColumns="False"
          IsReadOnly="True"
          FontWeight="Bold"
          RowHeaderWidth="0"
          GridLinesVisibility="Horizontal" HorizontalGridLinesBrush="White">
    <DataGrid.CellStyle>
        <Style TargetType="DataGridCell">
            <Setter Property="BorderThickness" Value="0"/>
            <!-- Remove the focus indication for the selected cell -->
            <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
        </Style>
    </DataGrid.CellStyle>
    <DataGrid.ColumnHeaderStyle>
        <Style TargetType="DataGridColumnHeader">
            <Setter Property="BorderThickness" Value="3"/>
            <Setter Property="BorderBrush" Value="White"/>
            <Setter Property="Background" Value="LightGray"/>
            <Setter Property="Foreground" Value="DimGray"/>
            <Setter Property="HorizontalContentAlignment" Value="Center"/>
        </Style>
    </DataGrid.ColumnHeaderStyle>
    <DataGrid.RowStyle>
        <Style TargetType="DataGridRow">
            <Setter Property="Background" Value="WhiteSmoke"/>
            <Setter Property="FontFamily" Value="Microsoft Sans Serif"/>
            <Setter Property="FontWeight" Value="Bold"/>
        </Style>
    </DataGrid.RowStyle>
    <DataGrid.Columns>
        <DataGridTemplateColumn Header="Sign" MinWidth="100" Width="Auto">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Grid>
                        <Ellipse Width="20" Height="20" Fill="LightGray"/>
                        <Ellipse Width="16" Height="16" Fill="DimGray"/>
                    </Grid>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTextColumn MinWidth="100" Width="Auto" Header="No." Binding="{Binding Age}" Foreground="Peru"/>
        <DataGridTextColumn MinWidth="200" Width="Auto" Header="Command Name" Binding="{Binding Name}" Foreground="LimeGreen"/>
    </DataGrid.Columns>
    <DataGrid.GroupStyle>
        <GroupStyle ContainerStyle="{StaticResource GroupHeaderStyle}">
        </GroupStyle>
    </DataGrid.GroupStyle>
</DataGrid>

答案 1 :(得分:0)

我添加了Command以测试所选项目的删除,它仍然可以工作。 这就是我所做的。

Made Class DelegateCommand

 public class DelegateCommand : ICommand
    {
        private readonly Action<object> _execute;
        private readonly Func<object, bool> _canExecute;

        public DelegateCommand(Action<object> execute, Func<object, bool> canExecute = null)
        {
            if (execute == null)
            {
                throw new ArgumentNullException("execute");
            }
            _execute = execute;
            _canExecute = canExecute;
        }

        public bool CanExecute(object parameter)
        {
            return _canExecute == null || _canExecute(parameter);
        }

        public void Execute(object parameter)
        {
            _execute(parameter);
        }

        public event EventHandler CanExecuteChanged = delegate { };

        public void RaiseCanExecuteChanged()
        {
            CanExecuteChanged(this, EventArgs.Empty);
        }
    }

在TestVm中,我添加了ICommand的属性

public ICommand RemoveSelectedItem { get; private set; }

在构造函数ov TestVm中使用该命令。

RemoveSelectedItem = new DelegateCommand(OnRemoveSelecteditem);

和OnRemoveSelecteditem方法就是这样。

private void OnRemoveSelecteditem(object commandParam)
        {
            Collection.Remove((User)commandParam);
        }

在MainWindow内部我添加了Button只是为了调用这个命令:

<Button Content="RemoveSelectedItem"
                Command="{Binding RemoveSelectedItem}"
                CommandParameter="{Binding ElementName=dg,Path=SelectedItem}"
                Height="25"
                Width="150"
                VerticalAlignment="Bottom" />

它仍然有效:)您可以选择项目并单击该按钮将其删除。

答案 2 :(得分:-1)

我找到的最佳2个答案如下:

1)这里的答案wpf why get "NullReferenceException" when binding SelectedItem [Edit]是使用单向绑定 2)如果您需要保持与ViewModel的绑定,请改用SelectedIndex(然后通过ObservableCollection上的ElementAt方法简单地获取选定的值

第二个最终成为我的解决之道。