【问题标题】:Unable to bind inherited class to an datagrid wpf c#无法将继承的类绑定到数据网格 wpf c#
【发布时间】:2014-10-28 10:47:09
【问题描述】:
//In Test.xaml 

 <Grid>
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition Height="30"></RowDefinition>
        </Grid.RowDefinitions>
        <DataGrid  Grid.Row="0"  AutoGenerateColumns="False" ItemsSource="{Binding}"   Name="dtGridTran" HorizontalAlignment="Left"   CanUserAddRows="True"   >
            <DataGrid.Columns>
                <DataGridTextColumn Header="X" Binding="{Binding Path=X, UpdateSourceTrigger=PropertyChanged}"   Width="200"/>               
                <DataGridTextColumn Header="Y" Binding="{Binding Path=Y, UpdateSourceTrigger=PropertyChanged}" Width="200"  />
            </DataGrid.Columns>
        </DataGrid>
        <Label Grid.Row="1" Content=" Total Sum of x and Y">

        </Label>
        <TextBox  Grid.Row="1" Text="{Binding Path=Total, UpdateSourceTrigger=PropertyChanged}" Margin="150,0,0,0" Width="100"></TextBox>       
    </Grid>

//In Test.xaml.cs file
public partial class Test : Page
    {

        Derivedclass D = new Derivedclass();
        public Test()
        {
            InitializeComponent();
            this.DataContext = D;
            dtGridTran.ItemsSource = new TestGridItems();
        }

    }

public class TestGridItems : List<Derivedclass>
{
}

// In Base class
public class Baseclass : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private int mTotal = 0;
        private int mID = 0;

        public int Total
        {
            get { return mTotal; }
            set
            {
                mTotal = value; OnPropertyChanged("Total");
            }
        }
        public int ID
        {
            get { return mID; }
            set { mID = value; }
        }
        public string Item = "xxx";
        // Create the OnPropertyChanged method to raise the event 
        protected void OnPropertyChanged(string PropertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(PropertyName));
            }
        }

    }

In Derivedclass.cs

    public class Derivedclass : Baseclass, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private int mX = 0;
        private int mY = 0;
        public int X
        {
            get { return mX; }
            set
            {
                mX = value;
                base.Total = base.Total + mX;
                                OnPropertyChanged("Total");

            }
        }
        public int Y
        {
            get { return mY; }
            set
            {
                mY = value;
                base.Total = base.Total + mY;
                OnPropertyChanged("Total");
            }
        }
         // Create the OnPropertyChanged method to raise the event 
        protected void OnPropertyChanged(string PropertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(PropertyName));
            }
        }
    }
}

这里我试图找到 x 和 y 值的总和。但是 m 总和为零。总属性在基类中。我想要在文本框中显示的 x 和 y 列的总和。但是在添加多个值时,基类的 Total 属性返回零。

【问题讨论】:

  • 为什么要设置 base.Total 而不是 Total?我认为您设置的值只有在实例被转换为 BaseClass 时才会明显。
  • 总属性在 BaseClass 中。我想从派生类中为基类属性设置一个值
  • 您在哪里设置派生类对象的属性?在这样做之前。DataContext = D;
  • dtGridTran.ItemsSource = new TestGridItems();
  • 公共类 TestGridItems : List { }

标签: c# wpf class datagrid inherited


【解决方案1】:

您正在显示的 Total 属于您首先创建的单个 D 对象,但与您的 DerivedClasses 列表没有任何联系(我必须说,您奇怪地将其包装为一个单独的类) .仅仅因为有一个基类并不意味着它的属性将“全局”存储值,因此任何实例都可以读取它们。 static 属性将充当一个,但在您描述的场景中,在您的类之外指定一个新的属性/变量将更有意义,这将代表一个总和。此外,在 setter 中将数字相加不会很好,因为它会记录 任何 值更改,并且您最终可能会多次添加相同的属性(除非这是您想要实现的目标...)。

编辑:

首先,我将创建一个 ViewModel 类,您的页面的 DataContext 将绑定到该类:

public class MyViewModel : INotifyPropertyChanged
{
    // backing fields, etc...

    public List<DerivedClass> Items
    {
        get { return items; }
        set
        {
            items = value;
            OnPropertyChanged("Items");
        }
    }

    public int Sum
    {
        get
        {
            return this.Items != null ? this.Items.Sum(i => i.X + i.Y) : 0;
        }
    }

   ...       

   public void PopulateItems()
   {
       this.Items = MyMethodToGetItems();
       foreach (var item in this.Items)
       {
           item.PropertyChanged += this.ItemPropertyChanged;
       }
   }

    private void ItemPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
    {
        if (propertyChangedEventArgs.PropertyName == "X" || propertyChangedEventArgs.PropertyName == "Y")
        {
            OnPropertyChanged("Sum");
        }
    }
}

PopulateItems 方法中,它将订阅集合中每个项目的PropertyChaned 事件。如果触发偶数的属性是 X 或 Y,它将触发另一个事件以重新计算总和 (ItemPropertyChanged)。

【讨论】:

    【解决方案2】:

    我相信您遇到的问题是因为 INotifyPropertyChanged 的​​单独实现,从 DerivedClass 中删除了实现,应该没问题,绑定会自动挂钩到类 PropertyChanged 事件,但因为这是一个不同的事件基类它没有捕获任何基类 PropertyChanged 被触发的事件。

    所以 DerivedClass 应该是这样的

    public class Derivedclass : Baseclass
    {
        private int mX = 0;
        private int mY = 0;
        public int X
        {
            get { return mX; }
            set
            {
                mX = value;
                base.Total = base.Total + mX;
                OnPropertyChanged("Total");
    
            }
        }
        public int Y
        {
            get { return mY; }
            set
            {
                mY = value;
                base.Total = base.Total + mY;
                OnPropertyChanged("Total");
            }
        }
    }
    

    如果您查看 Visual Studio 给您的警告,它可能已经告诉您“方法覆盖非虚拟基类方法,使基类方法为虚拟或使用关键字 new”

    另外我认为你的总计算搞砸了,你总是加总而不是只做 X + Y。

    【讨论】:

    • 我认为他试图在网格中显示他所有元素的总和,这样无论有 X+Y 还是 base.Total + mX 都不会起作用。
    • 啊,好的,我现在明白了。那么他肯定需要像你说的那样填写一个列表。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-28
    • 2011-01-31
    • 2017-05-14
    • 2012-11-21
    • 1970-01-01
    相关资源
    最近更新 更多