【问题标题】:How to create this shared class member or property如何创建此共享类成员或属性
【发布时间】:2014-07-16 00:07:48
【问题描述】:

我的 XAML 引用了以下类。这个类有一堆属于按钮的附加属性和行为,所以它在 UI 方面。

其中一些行为设置了 current_cell_match 并且这些行为中的每一个都有自己的类,这就是为什么我将它放在一个静态类中以便可以共享。

public static class SearchVariables
{
    public static DataGridCellInfo current_cell_match;

    public static void setCurrentCell(Object dgi, DataGridColumn dgc, string property_name)
    {
        current_cell_property = property_name;
        if (property_name == null)
            current_cell_match = new DataGridCellInfo();
        else
            current_cell_match = new DataGridCellInfo(dgi, dgc);
    }
}

我不确定 current_cell_match 应该是成员、属性还是附加属性。我真的不需要将它用作任何 UI 控件上的属性,所以我正在考虑前两个中的一个。

我会将它与 MultiBinding 转换器一起使用,所以我需要知道它的值何时发生变化。所以我倾向于使用 PropertyChangedEventHandler 的属性。但是静态类没有实例,所以这不起作用,没有'this'。

public event PropertyChangedEventHandler PropertyChanged;

private void RaisePropertyChanged(string propertyName)
{
    if (PropertyChanged != null)
        PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}

这是我最后要使用的多重绑定:

<Setter Property="helpers:SearchBehaviours.IsTextMatchFocused">
    <Setter.Value>
        <MultiBinding Converter="{StaticResource SelectedSearchValueConverter}" FallbackValue="False">
            <Binding Path="(helpers:SearchBehaviours.IsFindPopupOpen)" RelativeSource="{RelativeSource Self}"/>
            <Binding Source="{x:Static helpers:SearchVariables.current_cell_match}"/>
        </MultiBinding>
    </Setter.Value>
</Setter>

有人可以帮我构建 current_cell_match 吗?

【问题讨论】:

    标签: c# wpf properties dependency-properties


    【解决方案1】:

    关于“但是静态类没有实例,所以这不起作用,没有'this'。”您可以执行以下操作:

    public event PropertyChangedEventHandler PropertyChanged;
    
    private void RaisePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(typeof(this), new System.ComponentModel.PropertyChangedEventArgs(propertyName));
    }
    

    这将向 PropertyChanged 侦听器指示发送者不是实例,并且侦听器仍然能够看到发送者类型。

    要更新视图,您需要实现接口 INotifyPropertyChanged。但这在使用静态属性时可能非常棘手。相反,我建议实现单例模式,并使您的静态属性成为“正常”属性。静态类和单例模式之间的区别并没有那么大。所以这可能是你要走的路。

    这是一个例子。 Xaml:

    <Binding Source="{x:Static local:MyClass.Instance}" Path="MyInt" />
    

    代码:

    public class MyClass : INotifyPropertyChanged
    {
        private Random random;
    
        private int m_MyInt;
        public int MyInt
        {
            get
            {
                return m_MyInt;
            }
            set
            {
                if ( m_MyInt == value )
                {
                   return;
                }
    
                m_MyInt = value;
                NotifyPropertyChanged();
            }
        }
    
        private static MyClass m_Instance;
        public static MyClass Instance
        {
            get
            {
                if ( m_Instance == null )
                {
                    m_Instance = new MyClass();
                }
    
                return m_Instance;
             }
        }
    
        private MyClass()
        {
            random = new Random();
            m_MyInt = random.Next( 0, 100 );
    
            Timer timer = new Timer();
            timer.Interval = 1000;
            timer.Elapsed += timer_Elapsed;
            timer.Start();
        }
    
        private void timer_Elapsed( object sender, ElapsedEventArgs e )
        {
            MyInt = random.Next( 0, 100 );
        }
    
        #region INotifyPropertyChanged Members
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        private void NotifyPropertyChanged( [CallerMemberName] String propertyName = "" )
        {
            if ( PropertyChanged != null )
            {
                PropertyChanged( this, new PropertyChangedEventArgs( propertyName ) );
            }
        }
    
        #endregion
    }
    

    编码愉快:-)

    【讨论】:

      【解决方案2】:

      您说我将使用 MultiBinding 转换器,因此基本上将您的选择限制为使用 DependencyProperty 或附加属性。来自 MSDN 上的Custom Dependency Properties 页面:

      什么时候应该实现依赖属性?
      ...
      • 您希望您的属性支持数据绑定。
      ...

      但是,由于附加属性确实用于扩展预先存在的 UI 控件的功能,因此您现在的选择似乎很简单……您剩下的唯一选择是使用 DependencyProperty。从 MSDN 上的自定义依赖属性页面:

      何时创建附加属性?
      当有理由为定义类以外的类提供属性设置机制时,您可以创建附加属性。最常见的场景是布局。现有布局属性的示例是 DockPanel.Dock、Panel.ZIndex 和 Canvas.Top。这里启用的场景是,作为布局控制元素的子元素存在的元素能够单独向其布局父元素表达布局要求,每个元素都设置一个属性值,父元素定义为附加属性。

      使用附加属性的另一种情况是,当您的类表示服务时,您希望类能够更透明地集成服务。
      ...

      从技术上讲,您可以使用附加属性,但如果不使用 UI,它不会为您提供任何额外的功能,而且使用起来比简单的 DependencyProperty 更尴尬。此外,为了您的信息,您应该阅读程序员论坛上对Is it bad practice to use public fields? 问题的接受答案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-08
        • 2017-10-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多