【问题标题】:Datagrid inside a Custom control is not updating自定义控件内的数据网格未更新
【发布时间】:2015-06-17 18:42:31
【问题描述】:

在我的自定义控件中,有一个 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 windows 中的用法:

xml 代码:

    <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 row view model:

/// <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 没有显示添加到集合中的新元素。调试时,我可以看到我的集合包含许多元素(每次单击 (+) 按钮时一个元素),但这些元素未显示在视图中。

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

谢谢。

【问题讨论】:

    标签: c# wpf xaml datagrid


    【解决方案1】:

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

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

    没有称为 CustonDataGrid 的元素,因此这些元素从未被反射。

    改成

    <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();
        }
    }
    

    MainWindow.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));
        }
    }
    

    我希望它也适用于你。

    【讨论】:

    • 感谢您的回答!问题出在 ElementName=CustonDataGrid 的 CustonDatagrid.xaml 中。现在完美运行!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-08
    • 1970-01-01
    • 1970-01-01
    • 2017-04-14
    • 1970-01-01
    相关资源
    最近更新 更多