c# - 自定义控件内的数据网格未更新

标签 c# wpf xaml datagrid

在我的自定义控件中有一个 DataGrid 和两个按钮,一个用于在此 DataGrid 中添加行,另一个按钮用于删除元素。

(因为我的声誉,我不能在这里张贴图片,抱歉!):-(

我的自定义控件背后的代码:

    /// <summary>
    /// Interaction logic for UserControl1.xaml
    /// </summary>
    public partial class CustonDatagrid : UserControl
    {
        public CustonDatagrid()
        {
            InitializeComponent();
        }

        #region DependencyProperty Content

        /// <summary>
        /// Registers a dependency property as backing store for the Content property
        /// </summary>
        public static readonly DependencyProperty ColectionProperty =
            DependencyProperty.Register("Colection",
            typeof(ObservableCollection<object>),
            typeof(CustonDatagrid),
            new FrameworkPropertyMetadata(null,
                  FrameworkPropertyMetadataOptions.AffectsRender |
                  FrameworkPropertyMetadataOptions.AffectsParentMeasure));

        /// <summary>
        /// Gets or sets the Content.
        /// </summary>
        /// <value>The Content.</value>
        public ObservableCollection<object> Colection
        {
            get { return (ObservableCollection<object>)GetValue(ColectionProperty); }
            set { SetValue(ColectionProperty, value); }
        }

        #endregion

        public static readonly RoutedEvent AddButtonEvent = EventManager.RegisterRoutedEvent(
            "AddButtonClick",
            RoutingStrategy.Bubble, 
            typeof (RoutedEventHandler),
            typeof (CustonDatagrid));

        public event RoutedEventHandler AddButtonClick
        {
            add { AddHandler(AddButtonEvent, value); }
            remove { RemoveHandler(AddButtonEvent, value);}
        }

        private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
        {
            var newEventArgs = new RoutedEventArgs(AddButtonEvent);
            RaiseEvent(newEventArgs);
        }
    }

我的.xaml:

    <UserControl x:Class="WpfCustomControlLibrary1.CustonDatagrid"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300" Name="CustonDataGrid">
    <Grid>
            <DockPanel LastChildFill="True" >
                <StackPanel DockPanel.Dock="Bottom" HorizontalAlignment="Right" Orientation="Horizontal">
                    <Button Margin="5" Width="20" Click="ButtonBase_OnClick" >+</Button>
                <Button Margin="5" Width="20">-</Button>
            </StackPanel>
                <DataGrid ItemsSource="{Binding ElementName=CustonDataGrid, Path=Colection}" DockPanel.Dock="Top"></DataGrid>
            </DockPanel>
    </Grid>
</UserControl>

以及在 wpf 窗口中的用法:

xaml 代码:

    <Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:wpfCustomControlLibrary1="clr-namespace:WpfCustomControlLibrary1;assembly=WpfCustomControlLibrary1"
        Title="MainWindow" Height="350" Width="525"
        DataContext="{Binding RelativeSource={RelativeSource Self}, Path=Model}"
        >

    <Grid>
        <wpfCustomControlLibrary1:CustonDatagrid Colection="{Binding Path=Colection}" AddButtonClick="CustonDatagrid_OnAddButtonClick">

        </wpfCustomControlLibrary1:CustonDatagrid>
    </Grid>
</Window>

以及 + View Model + datagrid 行 View 模型背后的代码:

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{

    public MainWindow()
    {
        Model = new Model();
        InitializeComponent();
    }

    public Model Model { get; set; }

    private void CustonDatagrid_OnAddButtonClick(object sender, RoutedEventArgs e)
    {
        Model.AddElement();
    }
}

public class Model : INotifyPropertyChanged
{
    public ObservableCollection<DataGridRowModel> Colection { get; set; }

    public void AddElement()
    {
        if (Colection == null) Colection = new ObservableCollection<DataGridRowModel>();
        Colection.Add( new DataGridRowModel()
        {
            Name = "Test"
        });
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

public class DataGridRowModel
{
    public string Name { get; set; }
}

我遇到的问题是 Datagrid 没有显示添加到集合中的新元素。调试时,我可以看到我的集合有很多元素(每次单击 (+) 按钮时一个元素),但这些元素未显示在 View 中。

有人可以在我犯错或(可能)遗漏代码的地方给出提示吗?!?

谢谢。

最佳答案

你在 CustonDatagrid.xaml 中犯的一个小错误

<DataGrid ItemsSource="{Binding ElementName=CustonDataGrid, Path=Colection}" DockPanel.Dock="Top"></DataGrid>

没有名为 CustonDataGrid 的元素,因为这些元素从未被反射(reflect)出来。

改成

<DataGrid ItemsSource="{Binding Path=Colection}"></DataGrid>

我还在你的 MainWindow.cs 中做了一些小改动

public partial class MainWindow : Window
{
    public MainWindow()
    {
        Model = new Model();
        InitializeComponent();
        this.DataContext = Model;
    }

    public Model Model { get; set; }

    private void CustonDatagrid_OnAddButtonClick(object sender, RoutedEventArgs e)
    {
        Model.AddElement();
    }
}

主窗口.xaml

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:wpfCustomControlLibrary1="clr-namespace:WpfCustomControlLibrary1;assembly=WpfCustomControlLibrary1"
        Title="MainWindow" Height="350" Width="525">
    <ScrollViewer>
        <wpfCustomControlLibrary1:CustonDatagrid Colection="{Binding Colection,Mode=TwoWay}" AddButtonClick="CustonDatagrid_OnAddButtonClick">
        </wpfCustomControlLibrary1:CustonDatagrid>
    </ScrollViewer>
</Window>

Model.cs 添加了构造函数

public class Model : INotifyPropertyChanged
{
    public ObservableCollection<DataGridRowModel> Colection { get; set; }

    public Model()
    {
        Colection = new ObservableCollection<DataGridRowModel>();
    }
    public void AddElement()
    {
        Colection.Add(new DataGridRowModel { Name = "Test" });
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

我希望它也适用于您。

关于c# - 自定义控件内的数据网格未更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30899813/

相关文章:

c# - Windows Server 2008 R2 的 WebRequest 故障转移 TLS 1.2

c# - 获取枚举的描述并将其用作 MVC 中下拉列表的文本属性?

xaml - 如何使 RichTextBlock 中的超链接不完全不对齐?

c# - VS 代码 CSC : error CS1617: Invalid option '7.3' for/langversion

c# - 想要 C# 程序启动 WPF 应用程序

c# - 将文件拖放到 wpf/C# 应用程序时,如何维护 Windows 资源管理器中的文件顺序?

c# - 绕过循环依赖

c# - Xamarin.Forms.Xaml.XamlParseException : MarkupExtension not found

c# - Windows Azure 表中的 Like 语句等效项

c# - 存储在通用集合中后重载和多态行为发生变化