【发布时间】:2016-10-08 01:23:33
【问题描述】:
花了几天的谷歌搜索来解决这个问题,我希望你们中的一个人能够提供帮助。
我在 Grid 控件上有一个自定义依赖属性。首次创建 Observable Collection 时,它会正确更新。但是,当更新集合(在我的简化示例中按下更新按钮)并且调用 NotifyPropertyChanged 时,不会调用依赖属性的更新方法。正在调用绑定的值转换器并显示更新的数据(暗示绑定尚未被覆盖)
请注意,这是 Windows Universal,因此某些 WPF 绑定跟踪信息似乎不可用。
谁能说明为什么依赖属性的更新方法只在第一次调用而不是在调用 NotifyPropertyChanged 时调用?
罗伯特
<Page
x:Class="CustomBindingTest.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CustomBindingTest"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" Loaded="Page_Loaded">
<Page.Resources>
<local:DebugConverter x:Key="debug"/>
</Page.Resources>
<StackPanel Orientation="Vertical">
<Button Height="50" Click="Button_Click">Update</Button>
<Grid local:GridHelpers.Cells="{Binding Path=Cells, Mode=TwoWay, Converter={StaticResource debug}}" Height="500">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
</Grid>
</StackPanel>
</Page>
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
namespace CustomBindingTest
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page, INotifyPropertyChanged
{
public ObservableCollection<Cell> Cells { get; set; }
public MainPage()
{
this.InitializeComponent();
}
private void Page_Loaded(object sender, RoutedEventArgs e)
{
Cells = new ObservableCollection<Cell>();
Cells.Add(new Cell());
Cells.Add(new Cell());
Cells.Add(new Cell());
Cells.Add(new Cell());
Cells.Add(new Cell());
Cells.Add(new Cell());
Cells.Add(new Cell());
Cells.Add(new Cell());
Cells.Add(new Cell());
Cells.Add(new Cell());
Cells.Add(new Cell());
Cells.Add(new Cell());
DataContext = this;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Cells.Add(new Cell());
Cells.Add(new Cell());
Cells.Add(new Cell());
Cells.Add(new Cell());
Cells.Add(new Cell());
Cells.Add(new Cell());
NotifyPropertyChanged("Cells");
}
#region NotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(info));
}
}
#endregion
}
}
<UserControl
x:Class="CustomBindingTest.Cell"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CustomBindingTest"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<Grid Background="Green" Margin="5">
</Grid>
</UserControl>
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI;
using Windows.UI.Text;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
namespace CustomBindingTest
{
public class GridHelpers
{
#region Cells Property
/// <summary>
/// Adds the Cell objectss to Grid.
/// </summary>
public static readonly DependencyProperty CellsProperty =
DependencyProperty.RegisterAttached(
"Cells", typeof(ObservableCollection<Cell>), typeof(GridHelpers),
new PropertyMetadata(null, CellsChanged));
// Get
public static ObservableCollection<Cell> GetCells(DependencyObject obj)
{
return (ObservableCollection<Cell>)obj.GetValue(CellsProperty);
}
// Set
public static void SetCells(DependencyObject obj, ObservableCollection<Cell> value)
{
obj.SetValue(CellsProperty, value);
}
// Change Event - Add the Cells
public static void CellsChanged(
DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
if (!(obj is Grid) || e.NewValue == null)
return;
Grid grid = (Grid)obj;
List<Cell> cells = ((ObservableCollection<Cell>)e.NewValue).ToList();
if (cells != null)
{
if (cells.Count() == 0)
{
ShowEmpty(grid);
}
else
{
int rowCount = grid.RowDefinitions.Count();
int colCount = grid.ColumnDefinitions.Count();
for (int row = 0; row < rowCount; row++)
{
for (int col = 0; col < colCount; col++)
{
int index = (row * colCount) + col;
if (index < cells.Count())
{
Cell cell = cells[index];
Debug.WriteLine("Row {0} Col {1} Cell {2}", row, col, index);
cell.SetValue(Grid.ColumnProperty, col);
cell.SetValue(Grid.RowProperty, row);
grid.Children.Add(cell);
}
}
}
}
}
}
private static void ShowEmpty(Grid grid)
{
TextBlock text = new TextBlock();
text.Text = "[Empty Grid]";
text.FontSize = 24.0;
text.Foreground = new SolidColorBrush(Colors.Red);
text.FontWeight = FontWeights.Bold;
text.SetValue(Grid.ColumnProperty, 0);
text.SetValue(Grid.RowProperty, 0);
grid.Children.Add(text);
}
#endregion
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml.Data;
namespace CustomBindingTest
{
class DebugConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
}
【问题讨论】:
-
您可以直接编辑您的帖子,而不是在 cmets 中进行更新。这将使问题在未来更具可读性。