【问题标题】:UserControl DependencyProperty propertyChangedCallback not called未调用 UserControl DependencyProperty propertyChangedCallback
【发布时间】:2018-07-18 03:37:55
【问题描述】:

所以我在我的 xaml 中设置了一个 ItemsControl:

<ItemsControl ItemsSource="{Binding Items}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Grid>
                <local:ToggleButton Command="{Binding DataContext.ItemSelectedCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type WrapPanel}}}" 
                                    CommandParameter="{Binding DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Grid}}}" 
                                    Text="{Binding DataContext.ItemEnum, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Grid}}, Converter={StaticResource EnumToStringConverter}}" 
                                    IsActive="{Binding DataContext.Selected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Grid}}, UpdateSourceTrigger=PropertyChanged}"
                                    Width="96" 
                                    Height="88" 
                                    Margin="5" />
            </Grid>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

我有 4 个依赖属性 CommandCommandParameterTextIsActive。 前 3 个依赖属性正常工作,设置了文本,命令回调与参数一起工作。

IsActive 属性不起作用。 主视图模型中的 Items 属性定义为:

List<ItemViewModel> Items { get; set; }

ItemViewModel 定义为:

public class ItemViewModel : INotifyPropertyChanged
{
    public ItemViewModel()
    {
        this.Selected = true;
    }

    private bool? _selected;

    public event PropertyChangedEventHandler PropertyChanged;

    public ItemEnum ItemEnum { get; set; }

    public bool? Selected
    {
        get { return this._selected; }

        set
        {
            this._selected = value;
            this.OnPropertyChanged(nameof(this.Selected));
        }
    }

    protected virtual void OnPropertyChanged(string propertyName = null)
    {
        this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

ToggleButton.xaml.cs 文件中 IsActive 属性的依赖属性如下所示:

public static readonly DependencyProperty IsActiveProperty = DependencyProperty.Register(nameof(IsActive), typeof(bool?), typeof(ToggleButton), new PropertyMetadata(null, IsActiveSetCallback));

private static void IsActiveSetCallback(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
    var button = (ToggleButton)obj;

    button.IsActive = (bool)(e.NewValue ?? e.OldValue);0xa5, 0xa5));
}

我在主视图模型中的命令回调如下所示:

this.ItemSelectedCommand = 
      new DelegateCommand(
          itemVm =>
          {
               bool? setTo = !((ItemViewModel) itemVm).Selected;
               this.Items.ForEach(i => i.Selected = false);
               ((ItemViewModel) itemVm).Selected = setTo;
          });

同样,其他依赖属性(与IsActiveProperty 定义基本相同)正常工作,因此当我单击该项目时,将调用上述命令(通过断点验证),该项目的 Selected 标志被正确切换,但 IsActiveSetCallback永远不会被击中。我看不出我做错了什么,但很明显是有问题。

有人看到我看不到的东西吗?

提前致谢!

【问题讨论】:

    标签: wpf xaml mvvm


    【解决方案1】:

    在花了太多时间试图解决这个问题之后,我当然设法在发布这个问题后的半小时内自己解决了这个问题..

    我从 Microsoft DependencyProperty 文档中提取了这个,特别是关于“依赖属性设置优先级列表”的部分:

    本地价值。可以通过“包装器”属性的便利设置本地值,这也等同于在 XAML 中设置为属性或属性元素,或者通过使用特定实例的属性调用 SetValue API。如果您使用绑定或资源设置本地值,则它们各自的优先级就像设置了直接值一样。

    所以,我在 ToggleButton.xaml.cs 的两个地方设置了this.Active,一次在构造函数中作为默认值,一次在 IsActiveSetCallback 中。通过这样做,我覆盖了绑定,无论如何,这些电话都不是必需的。这么简单!

    【讨论】:

      猜你喜欢
      • 2019-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-06
      • 2012-03-02
      • 2011-01-04
      • 1970-01-01
      • 2012-06-06
      相关资源
      最近更新 更多