的DependencyProperty无法创建内部绑定时绑定未设置UpdateSourceTrigger明确

问题描述:

@Update适当UpdateSourceTrigger - 见下面更新,请的DependencyProperty无法创建内部绑定时绑定未设置UpdateSourceTrigger明确

我有一个是内部DataGridTemplateColumn使用UserControl。当我指定像这样的绑定{Binding MyProperty, UpdateSourceTrigger=PropertyChanged}它更新源。但是,我忽略了UpdateSourceTrigger它不更新源。

DependencyProperty创建这样的:

public static readonly DependencyProperty RatingValueProperty = DependencyProperty.Register(
    "RatingValue", typeof(int?), typeof(RatingControl), new FrameworkPropertyMetadata(default(int), 
     FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, 
     DependencyPropertyChangedCallback, 
     CoerceRatingValueCallback, 
     false, 
     UpdateSourceTrigger.PropertyChanged 
)); 

正如你可以看到下面的BindingDefault标志创建省略UpdateSourceTrigger时,与PropertyChanged标志,如果没有。

的 “不工作” 结合(见行26对两个例子):

0 _binding {System.Windows.Data.Binding} System.Windows.Data.BindingBase {System.Windows.Data.Binding} 
1 AsyncState null object 
2 BindingGroupName "" string 
3 BindsDirectlyToSource false bool 
4 Converter null System.Windows.Data.IValueConverter 
5 ConverterCulture null System.Globalization.CultureInfo 
6 ConverterCultureInternal null System.Globalization.CultureInfo 
7 ConverterParameter null object 
8 Delay 0 int 
9 ElementName null string 
10 FallbackValue {{DependencyProperty.UnsetValue}} object {MS.Internal.NamedObject} 
11 Flags Default System.Windows.Data.BindingBase.BindingFlags 
12 IsAsync false bool 
13 Mode Default System.Windows.Data.BindingMode 
14 NotifyOnSourceUpdated false bool 
15 NotifyOnTargetUpdated false bool 
16 NotifyOnValidationError false bool 
17 Path {System.Windows.PropertyPath} System.Windows.PropertyPath 
18 RelativeSource null System.Windows.Data.RelativeSource 
19 Source null object 
20 SourceReference null MS.Internal.Data.ObjectRef 
21 StringFormat null string 
22 TargetNullValue {{DependencyProperty.UnsetValue}} object {MS.Internal.NamedObject} 
23 TransfersDefaultValue true bool 
24 TreeContextIsRequired false bool 
25 UpdateSourceExceptionFilter null System.Windows.Data.UpdateSourceExceptionFilterCallback 
26 UpdateSourceTrigger Default System.Windows.Data.UpdateSourceTrigger 
27 ValidatesOnDataErrors false bool 
28 ValidatesOnExceptions false bool 
29 ValidatesOnNotifyDataErrors true bool 
30 ValidatesOnNotifyDataErrorsInternal true bool 
31 ValidationRules Count = 0 System.Collections.ObjectModel.Collection<System.Windows.Controls.ValidationRule> {MS.Internal.Controls.ValidationRuleCollection} 
32 ValidationRulesInternal Count = 0 System.Collections.ObjectModel.Collection<System.Windows.Controls.ValidationRule> {MS.Internal.Controls.ValidationRuleCollection} 
33 XPath null string 
34 _attachedPropertiesInPath 0 int 
35 _bindsDirectlyToSource false bool 
36 _doesNotTransferDefaultValue false bool 
37 _flags Default System.Windows.Data.BindingBase.BindingFlags 
38 _isAsync false bool 
39 _isSealed true bool 
40 _ppath {System.Windows.PropertyPath} System.Windows.PropertyPath 
41 _source {MS.Internal.Data.ExplicitObjectRef} MS.Internal.Data.ObjectRef {MS.Internal.Data.ExplicitObjectRef} 
42 _sourceInUse None System.Windows.Data.Binding.SourceProperties 
43 _values {MS.Internal.UncommonValueTable} MS.Internal.UncommonValueTable 
44 Static members  

“工作” 结合:

0 _binding {System.Windows.Data.Binding} System.Windows.Data.BindingBase {System.Windows.Data.Binding} 
1 AsyncState null object 
2 BindingGroupName "" string 
3 BindsDirectlyToSource false bool 
4 Converter null System.Windows.Data.IValueConverter 
5 ConverterCulture null System.Globalization.CultureInfo 
6 ConverterCultureInternal null System.Globalization.CultureInfo 
7 ConverterParameter null object 
8 Delay 0 int 
9 ElementName null string 
10 FallbackValue {{DependencyProperty.UnsetValue}} object {MS.Internal.NamedObject} 
11 Flags PropDefault | ValidatesOnNotifyDataErrors System.Windows.Data.BindingBase.BindingFlags 
12 IsAsync false bool 
13 Mode Default System.Windows.Data.BindingMode 
14 NotifyOnSourceUpdated false bool 
15 NotifyOnTargetUpdated false bool 
16 NotifyOnValidationError false bool 
17 Path {System.Windows.PropertyPath} System.Windows.PropertyPath 
18 RelativeSource null System.Windows.Data.RelativeSource 
19 Source null object 
20 SourceReference null MS.Internal.Data.ObjectRef 
21 StringFormat null string 
22 TargetNullValue {{DependencyProperty.UnsetValue}} object {MS.Internal.NamedObject} 
23 TransfersDefaultValue true bool 
24 TreeContextIsRequired false bool 
25 UpdateSourceExceptionFilter null System.Windows.Data.UpdateSourceExceptionFilterCallback 
26 UpdateSourceTrigger PropertyChanged System.Windows.Data.UpdateSourceTrigger 
27 ValidatesOnDataErrors false bool 
28 ValidatesOnExceptions false bool 
29 ValidatesOnNotifyDataErrors true bool 
30 ValidatesOnNotifyDataErrorsInternal true bool 
31 ValidationRules Count = 0 System.Collections.ObjectModel.Collection<System.Windows.Controls.ValidationRule> {MS.Internal.Controls.ValidationRuleCollection} 
32 ValidationRulesInternal Count = 0 System.Collections.ObjectModel.Collection<System.Windows.Controls.ValidationRule> {MS.Internal.Controls.ValidationRuleCollection} 
33 XPath null string 
34 _attachedPropertiesInPath 0 int 
35 _bindsDirectlyToSource false bool 
36 _doesNotTransferDefaultValue false bool 
37 _flags PropDefault | ValidatesOnNotifyDataErrors System.Windows.Data.BindingBase.BindingFlags 
38 _isAsync false bool 
39 _isSealed true bool 
40 _ppath {System.Windows.PropertyPath} System.Windows.PropertyPath 
41 _source {MS.Internal.Data.ExplicitObjectRef} MS.Internal.Data.ObjectRef {MS.Internal.Data.ExplicitObjectRef} 
42 _sourceInUse None System.Windows.Data.Binding.SourceProperties 
43 _values {MS.Internal.UncommonValueTable} MS.Internal.UncommonValueTable 
44 Static members  

如何解决这个,所以我不必在WPF中显式设置“UpdateSourceTrigger = PropertyChanged”。

@Update 2017年6月3日

我附上链接(click)的示例项目说明问题。请打开MainWindow.xaml并拨动#35-#39行。 #36行显示不工作行为,#39行显示工作行为。

线#36

<local:RatingControl StarsCount="5" RatingValue="{Binding Rating, PresentationTraceSources.TraceLevel=High}" IsReadonly="False" HorizontalContentAlignment="Center" /> 

线#39

<local:RatingControl StarsCount="5" RatingValue="{Binding Rating, UpdateSourceTrigger=PropertyChanged, PresentationTraceSources.TraceLevel=High}" IsReadonly="False" HorizontalContentAlignment="Center" /> 

@Edit - 请求XAML代码

<UserControl x:Class="so_44248130.RatingControl" 
      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="24" d:DesignWidth="240"> 
    <UserControl.Resources> 
     <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> 
     <BitmapImage x:Key="StarEmpty" UriSource="pack://application:,,,/so_44248130;component/star_black_empty.png" CacheOption="OnLoad" CreateOptions="IgnoreImageCache" /> 
     <BitmapImage x:Key="StarFull" UriSource="pack://application:,,,/so_44248130;component/star_black_full.png" /> 
    </UserControl.Resources> 
    <Grid> 
     <ItemsControl ItemsSource="{Binding StarsList, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"> 
      <ItemsControl.ItemsPanel> 
       <ItemsPanelTemplate> 
        <StackPanel Orientation="Horizontal" /> 
       </ItemsPanelTemplate> 
      </ItemsControl.ItemsPanel> 
      <ItemsControl.ItemTemplate> 
       <DataTemplate> 
        <Grid> 
         <Button Grid.Row="0" Grid.Column="0" Width="24" Height="24" MaxHeight="24" Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" Tag="{Binding}" Padding="0" HorizontalContentAlignment="Center" Click="ButtonBase_OnClick"> 
          <Grid> 
           <Grid.RowDefinitions> 
            <RowDefinition /> 
           </Grid.RowDefinitions> 
           <Grid.ColumnDefinitions> 
            <ColumnDefinition Width="24" /> 
           </Grid.ColumnDefinitions> 

           <Rectangle Grid.Row="0" Grid.Column="0" Width="{Binding EmptyStarWidth}" Height="24" HorizontalAlignment="Left"> 
            <Rectangle.Fill> 
             <ImageBrush ImageSource="{StaticResource StarEmpty}" 
             TileMode="Tile" 
             Stretch="Uniform" 
             AlignmentY="Top" 
             Viewport="0,0,24,3000" 
             ViewportUnits="Absolute" /> 
            </Rectangle.Fill> 
           </Rectangle> 
           <Rectangle Grid.Row="0" Grid.Column="0" Width="{Binding FullStarWidth}" Height="24" HorizontalAlignment="Left"> 
            <Rectangle.Fill> 
             <ImageBrush ImageSource="{StaticResource StarFull}" 
             TileMode="Tile" 
             Stretch="Uniform" 
             AlignmentY="Top" 
             Viewport="0,0,24,3000" 
             ViewportUnits="Absolute" /> 
            </Rectangle.Fill> 
           </Rectangle> 
          </Grid> 
         </Button> 
         <Rectangle Grid.Row="0" Grid.Column="0" Height="24" Width="24" Visibility="{Binding IsReadonly, Converter={StaticResource BooleanToVisibilityConverter}}" Fill="#02FFFFFF" /> 
        </Grid> 
       </DataTemplate> 
      </ItemsControl.ItemTemplate> 
     </ItemsControl> 
    </Grid> 
</UserControl> 
+1

无论如何,FrameworkPropertyMetadata类的'DefaultUpdateSourceTrigger'属性的值是'PropertyChanged',因此您可以使用FrameworkPropertyMetadata构造函数来创建更少的参数。也就是说,我所创建的所有具有“BindsTwoWayByDefault”的依赖项属性都会在'PropertyChanged'上更新它们的源代码,而不会出现任何问题,所以目前还不清楚为什么您的代码不符合它。 – Clemens

+0

@Clemens我编辑了我的问题(已添加链接到示例项目),请亲自看看 – user2475983

+0

我们可以看到RatingControl的XAML吗? –

我已经想通了... ...一部分

在问题链接的示例项目应该定位到RatingControl.xaml.cs文件,线#206-#228(click)。这是ButtonBase_OnClick方法。正好在if (star.Value ==〜部分我添加了绑定的强制UpdateSource。见下面的代码。

if (star.Value == RatingValue) 
{ 
    RatingValue = 0; 
} 
else 
{ 
    RatingValue = star.Value; 
} 

BindingExpression binding = GetBindingExpression(RatingValueProperty); 
if (binding != null) 
{ 
    binding.UpdateSource(); 
} 

这迫使的BindingSource更新并解决此问题(这是某种形式的补救措施可能..但也许它会把人在正确的方向后真正有效的答案)。

注:

在调试我检查接收BindingExpression并命名为IsUpdateOnPropertyChanged的属性设置为false出于某种原因。我相信它应该设置为true但是我缺乏关于WPF内部知识的知识以将其作为答案发布,因此是“注释”区域。

是否有使用FrameworkPropertyMetadata任何具体的原因是什么?

如果你只是备份一个属性,然后尝试使用PropertyMetadata

详情请参阅here

+0

没有具体原因。我已经将'FrameworkPropertyMetadata'更改为'PropertyMetadata',但唯一的结果是我必须明确指定'Mode = TwoWay'在XAML的'Binding'中,所以..没有真正帮助:(。 – user2475983

+0

我得到了问题因为它无法找到源,请尝试使用' – Anurag

+0

是的,它似乎有所帮助,但它看起来像另一种解决方法,你能否详细说明为什么即使'DataContext'被UC继承了也无法找到源代码? – user2475983