如何创建此共享类成员或属性

本文关键字:共享 成员 属性 何创建 创建 | 更新日期: 2023-09-27 18:05:13

我有以下由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控件上使用它作为属性所以我考虑前两个中的一个。

我将使用它与一个多绑定转换器,所以我需要知道当它的值变化。我倾向于使用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吗?

如何创建此共享类成员或属性

关于"然而静态类没有实例,所以这不起作用,因为没有'this'."你可以这样做:

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

这将向PropertyChanged-listeners表明发送方不是一个实例,并且侦听器仍然能够看到发送方的类型。

要更新视图,您需要实现接口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
}

快乐编码:-)

你说我将使用它与一个多绑定转换器,所以基本上限制了你的选择使用DependencyProperty或附加属性。从MSDN上的自定义依赖项属性页面:

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

然而,作为附加属性是真正用于扩展已有的UI控件的功能,似乎你的选择现在很简单…你剩下的唯一选择就是使用DependencyProperty。从MSDN上的自定义依赖项属性页面:

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

使用附加属性的另一个场景是当你的类代表一个服务,并且你希望类能够更透明地集成服务。

从技术上讲,您可以使用附加属性,但没有UI使用,它不会为您提供任何额外的功能,而使用比简单的DependencyProperty更尴尬。此外,为了您的信息,您应该阅读对"使用公共字段是不好的做法吗?"