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

时间:2017-05-29 17:55:07

标签: c# wpf binding datagrid dependency-properties

@update - 请参阅下面的更新,

我已获得UserControl内使用的DataGridTemplateColumn。当我像这个{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
));

如下所示,Binding在省略Default的情况下使用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      

&#34;工作&#34;结合:

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      

如何解决这个问题,所以我不必设置&#34; UpdateSourceTrigger = PropertyChanged&#34;明确地在WPF中。

@update 2017-06-03

我已将链接(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>

2 个答案:

答案 0 :(得分:0)

我已经弄清楚......部分......

在相关链接的示例项目中,应该导航到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内部的知识来发布它作为答案,因此是“注释”区域。

答案 1 :(得分:-1)

是否有使用FrameworkPropertyMetadata的具体原因?

如果您只是备份某个媒体资源,请尝试使用PropertyMetadata

有关详细信息,请参阅here