只有数据模板列中的最后一个控件被更新。

6

我有一个带有2个DatePickersDataTemplate列,它们绑定了2个属性。当这些控件中的数据发生更改时,只有最后一个控件会得到更新。

        <sdk:DataGridTemplateColumn Width="300"  CanUserReorder="False" >              
         <sdk:DataGridTemplateColumn.CellTemplate>
               <DataTemplate>
                 <Grid MouseRightButtonDown="ActionsGrid_MouseRightButtonDown" Width="300" Height="40" MouseLeftButtonDown="ActionsGrid_MouseLeftButtonDown">
                        <StackPanel Orientation="Horizontal">
                             <TextBlock VerticalAlignment="Stretch" Width="100" Text="{Binding Start,  Converter={StaticResource DateConverter}}"
                                         Padding="2" HorizontalAlignment="Center" />
                             <TextBlock VerticalAlignment="Stretch" Width="100" Text="{Binding Due, Converter={StaticResource DateConverter}}"
                                         Padding="2" HorizontalAlignment="Center" />
                         </StackPanel>
                  </Grid>
                </DataTemplate>                                                  
          </sdk:DataGridTemplateColumn.CellTemplate>
    <sdk:DataGridTemplateColumn.CellEditingTemplate>
               <DataTemplate>
                     <StackPanel Orientation="Horizontal">
                       <sdk:DatePicker VerticalAlignment="Top" Width="100" SelectedDate="{Binding Start, Mode=TwoWay,}" Padding="2" />
                       <sdk:DatePicker VerticalAlignment="Top" Width="100" SelectedDate="{Binding Due, Mode=TwoWay, ValidatesOnDataErrors=True}"  Padding="2" />
                     </StackPanel>
               </DataTemplate>  
     </sdk:DataGridTemplateColumn.CellEditingTemplate>
   </sdk:DataGridTemplateColumn>

在这种情况下,如果我同时更新Start和Due,则只有Due被更新。另外,绑定工作正常,因为如果我在我的Model类中的Start上设置一个断点,它会被触发,但传递的值是原始的Start值。
编辑1: 经过一些调试,我发现如果我的DataTemplate中只有一个控件,它就可以正常工作。另外,当我更改日期时,断点会立即被触发。但是,如果我有多个控件,断点直到我离开列才会被触发,然后只有最后一个绑定起作用。
编辑2: 经过进一步调试,我注意到如果我只使用CellTemplate并且放弃CellEditTemplate,则它将正常工作。
     <sdk:DataGridTemplateColumn Width="300"  CanUserReorder="False" >              
             <sdk:DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                   <StackPanel Orientation="Horizontal">
                       <sdk:DatePicker VerticalAlignment="Top" Width="100" SelectedDate="{Binding Start, Mode=TwoWay,}" Padding="2" />
                       <sdk:DatePicker VerticalAlignment="Top" Width="100" SelectedDate="{Binding Due, Mode=TwoWay, ValidatesOnDataErrors=True}"  Padding="2" />
                  </StackPanel>
               </DataTemplate>  
     </sdk:DataGridTemplateColumn.CellEditingTemplate>
   </sdk:DataGridTemplateColumn>

EDIT 3

private void DatePicker_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
        {
            (sender as DatePicker).GetBindingExpression(DatePicker.SelectedDateProperty).UpdateSource();
        }

我能够通过使用selectedDatechange事件刷新控件上的绑定,然后刷新发送方上的绑定。

我仍然不确定为什么双向绑定不起作用。

有人能解释一下这是为什么吗?

编辑4

模型和属性

 public DateTime? Start 
        { 
            get { return _Start; } 
            set 
            { 
                _Start = value; Dirty = true; 

                if (_Start.HasValue && _Due.HasValue && _Start.Value > _Due.Value)
                    _dataErrors["Start"] = "Start date cannot be greater than the Due date";
                else
                    if (_dataErrors.ContainsKey("Start"))
                        _dataErrors.Remove("Start");
                NotifyPropertyChanged(); NotifyPropertyChanged("CalcStatus");
            } 
        }
        public DateTime? Due 
        { 
            get { return _Due; } 
            set 
            { 
                _Due = value; Dirty = true; 
                if (_Start.HasValue && _Due.HasValue && _Start.Value > _Due.Value)
                    _dataErrors["Start"] = "Start date cannot be greater than the Due date";
                else
                    if (_dataErrors.ContainsKey("Start"))
                        _dataErrors.Remove("Start");
                NotifyPropertyChanged("Due"); NotifyPropertyChanged("CalcStatus");
            }
        }

展示与之绑定的相关视图模型属性。你是否正确实现了属性更改通知? - Nkosi
什么是WPF标签?由于客户需求,我们仍在使用Silverlight 4,因此不支持UpdateSourceTrigger PropertyChanged。 - Abhi.Net
我没有得到任何回应,所以我只是添加了WPF标签,因为它也是基于XAML的。实际上,我正在使用事件处理程序模拟更新源触发器,并且一切都正常工作。我只想知道为什么属性不会仅通过绑定进行更新。 - Abhi.Net
你的Start setter里不是需要NotifyPropertyChanged("Start");而不是NotifyPropertyChanged();吗? - Belterius
那就是导致问题的原因,但那不是一个错误。我使用了带有默认值的[CallerMember]属性,所以我不必传递PropertyName,这在除dDataTemplate列之外都运行良好。我将在下面的答案中进行更详细的解释。 - Abhi.Net
显示剩余4条评论
1个回答

2

好的,我认为我终于解决了它。我仍然不确定为什么它之前不能工作,但我将创建一个新的小项目并尝试找出原因。

发生的事情是我通过传递[CallerMemberName]来修改我的NoitifyPropertyChangedEvent,这样调用它的属性名称会自动传递。这意味着如果我更改名为“Start”的属性,我就不必担心更新NotifyPropertyChanged("Start")了。

 public event PropertyChangedEventHandler PropertyChanged;

        public void NotifyPropertyChanged([CallerMemberName] string propertyName =null)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

对于所有属性,这个方法都是有效的,但是当我使用 DataTemplateColumn 时会出现问题。 将其转换回标准代码,并明确传递属性名称可以解决我的问题。

public event PropertyChangedEventHandler PropertyChanged;

        public void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接