【问题标题】:How to modify inner control property by setting container control dependency property?如何通过设置容器控件依赖属性来修改内部控件属性?
【发布时间】:2012-05-30 07:25:24
【问题描述】:

我在 WPF 中创建一个控件,它有一个标签,我创建了一个依赖属性来修改标签的可见性属性。

我的问题是我无法在分配依赖属性的同时更改标签的可见性属性。

我的代码如下:

public static readonly DependencyProperty captionVisibleProperty = DependencyProperty.Register(
                                                                            "CaptionVisible",
                                                                            typeof(bool),
                                                                            typeof(MyCustomControl));

    public bool CaptionVisible
    {
        get
        {
            return (bool)GetValue(captionVisibleProperty);
        }
        set
        {
            SetValue(captionVisibleProperty, value);
            ShowCaption();
        }
    }

    private void ShowCaption()
    {
        if (CaptionVisible)
        {
            captionLabel.Visibility = System.Windows.Visibility.Visible;
        }
        else
        {
            captionLabel.Visibility = System.Windows.Visibility.Collapsed;
        }
    }

如您所见,我尝试在设置属性时调用 ShowCaption() 方法,但没有任何反应。

那么,我应该怎么做才能完成它?

希望有人可以帮助我。提前谢谢你。

【问题讨论】:

    标签: c# wpf properties wpf-controls


    【解决方案1】:

    我已经找到了解决这个问题的方法:

    如果您需要将嵌套控件依赖属性链接到容器控件依赖属性,您可以这样做:

         public static readonly DependencyProperty captionLabelVisibilityProperty = DependencyProperty.Register(
                                                                                        "CaptionVisibility",
                                                                                        typeof(Visibility),
                                                                                        typeof(MyContainerControl),
                                                                                        new FrameworkPropertyMetadata(
                                                                                            VisibilityPropertyChangedCallback));
    
        public Visibility CaptionVisibility
        {
            get
            { return (Visibility)GetValue(captionLabelVisibilityProperty); }
    
            set
            { SetValue(captionLabelVisibilityProperty, value); }
        }
    
        private static void VisibilityPropertyChangedCallback(DependencyObject controlInstance, DependencyPropertyChangedEventArgs args)
        {
            MyContainerControl myContainerControlInstance = (MyContainerControl)controlInstance;
            myContainerControlInstance.myLabel.Visibility = (Visibility)args.NewValue;
        }
    

    【讨论】:

      【解决方案2】:

      ShowCaption() 不应该是必要的。相反,只需将标签的 Visibility 属性绑定到 xaml 中的 CaptionVisible 属性。最好遵循Model-View-ViewModel 设计模式来保持您的代码井井有条。这意味着将用于控制用户界面(视图)的逻辑放在单独的 ViewModel 类中,然后将 ViewModel 分配给该 View 的 DataContext 属性。

      这将使绑定更容易。在 WPF 中引用属于用户界面元素的属性有时会有点麻烦。根据约定,WPF 的绑定系统专门设计用于轻松获取用户界面元素的 DataContext 的内容。

      您还需要使用方便的BooleanToVisiblityConverter 来进行绑定,因为Visibility 属性的类型不是bool。我喜欢把它放在窗口(或控件)的资源字典中以便于访问:

      <Window.Resources>
          <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
      </Window.Resources>
      
      
      <Label Visibility="{Binding Path=CaptionVisible, 
                                  Converter={StaticResource BooleanToVisibilityConverter}}"> 
          <!-- label content -->
      </Label>
      

      附带说明,除非 CaptionVisible 将成为绑定的目标,否则将其作为依赖属性是矫枉过正的。在此绑定中,它只是源,因此只需实现 INotifyPropertyChanged 就足够了:

      class MyViewModel : INotifyPropertyChanged
      {
      
          public event PropertyChangedEventHandler PropertyChanged;
      
          protected void RaisePropertyChanged(string propertyName)
          {
              var handler = PropertyChanged;
              if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
          }
      
          private bool _captionVisible;
          public bool CaptionVisible
          {
              get { return _captionVisible; }
              set
              {
                  if(_captionVisible != value)
                  {
                      _captionVisible = value;
                      RaisePropertyChanged("CaptionVisible");
                  }
              }
          }
      }
      

      【讨论】:

      • 感谢您的回复,@Sean U,但它对我不起作用,实际上我将我的属性类型更改为可见性但它仍然不起作用
      • 绑定可能不太正确。您是否看到程序运行时“输出”窗口中出现任何错误?
      • 不,我没有,简单的没有任何反应。由于我将返回类型更改为“可见性”,因此我在 xaml 文件中写了这个:Visibility="{Binding CaptionVisibility}",我也尝试了 Visibility="{Binding Path=CaptionVisibility}" 但这些也不起作用
      • CaptionVisibility 属于哪个类?如果它仍在控件中,那么您还需要指定在哪个控件中查找绑定。
      • CaptionVisibility 属性和标签属于同一类,因为我正在尝试开发自己的控件
      猜你喜欢
      • 1970-01-01
      • 2011-05-25
      • 1970-01-01
      • 2016-01-19
      • 2015-08-23
      • 1970-01-01
      • 1970-01-01
      • 2019-06-15
      • 1970-01-01
      相关资源
      最近更新 更多