C# 用依赖属性替换非平凡的getter

C# 用依赖属性替换非平凡的getter,c#,.net,wpf,data-binding,dependency-properties,C#,.net,Wpf,Data Binding,Dependency Properties,我最近开始尝试为我的自定义类进行数据绑定和实现DependencyProperties。这一切都很好,可能性也很令人兴奋,然而,我遇到了一个问题,这个问题可能只能通过稍微修改整个类设计来解决。我想确保这是唯一的选择,我不会错过任何东西 因此,我的类存储有关用户导入到应用程序中的视频文件的信息。除其他属性外,它还包含: public class VideoFile { public string FilePath { get; protected set; } public ui

我最近开始尝试为我的自定义类进行数据绑定和实现DependencyProperties。这一切都很好,可能性也很令人兴奋,然而,我遇到了一个问题,这个问题可能只能通过稍微修改整个类设计来解决。我想确保这是唯一的选择,我不会错过任何东西

因此,我的类存储有关用户导入到应用程序中的视频文件的信息。除其他属性外,它还包含:

public class VideoFile {

    public string FilePath { get; protected set; }
    public uint ID { get; protected set; ]
    public string Extension { get { return Path.GetExtension(FilePath); } }
    public string FileName { get { return Path.GetFilename(FilePath); } }

}
因此,我成功地用DependencyProperty替换了FilePath。但是,在UI中,我主要只想显示文件名,它使用一些逻辑来提供其值。据我所知,以下是我的选择:

  • 我可以简单地为FileName和Extension创建dependencProperties,并在构造函数中设置它们的值,但这是多余的;我在文件路径中已经有了这些信息,所以我想避免使用这个选项
  • 创建ValueConverter,一个用于显示文件名,一个用于显示扩展名,并在我的绑定中使用它们
  • 我只见过几次面,所以我不确定。我可以用它们来做这个用途吗?或者,我只是遇到了它们存在的主要原因之一吗?:)

    最后但并非最不重要的是,当ValueConverter不是正确的方法时,有人能想到类似的情况吗?我不想直接跳到它们上面,只想意识到它不起作用,因为“那一个”属性不能用这种方式表示。

    不要复制数据

    首选
    Binding
    IValueConverter
    ,因为这样,每当
    FilePath
    更改时,
    扩展名和
    文件名也会在UI中更新

    当然,您也可以在
    文件路径
    的setter中为他们提出
    属性更改
    ,但这是一种不好的做法,因为
    文件路径
    不必关心谁/什么人使用它

    然后,该类看起来像:

    public class VideoFile : INotifyPropertyChanged {
    
        string m_FilePath;
        public string FilePath 
        { 
           get { return m_FilePath; } 
           protected set
           {
              if(value != m_FilePath)
              {
                 m_FilePath = value;
                 RaisePropertyChanged(() => this.FilePath);
              }
           }
        }
        public uint ID { get; protected set; }
    
        #region INotifyPropertyChanged Members
    
        public event PropertyChangedEventHandler PropertyChanged;
        protected void RaisePropertyChanged<T>(Expression<Func<T>> _PropertyExpression)
        {
            RaisePropertyChanged(PropertySupport.ExtractPropertyName(_PropertyExpression));
        }
    
        protected void RaisePropertyChanged(String _Prop)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(_Prop));
            }
        }
    
        #endregion
    }
    
    公共类视频文件:INotifyPropertyChanged{
    字符串m_文件路径;
    公共字符串文件路径
    { 
    获取{return m_FilePath;}
    保护集
    {
    if(值!=m_文件路径)
    {
    m_FilePath=值;
    RaisePropertyChanged(()=>this.FilePath);
    }
    }
    }
    公共uint ID{get;protected set;}
    #区域INotifyProperty更改成员
    公共事件属性更改事件处理程序属性更改;
    受保护的void RaisePropertyChanged(表达式_PropertyExpression)
    {
    RaisePropertyChanged(PropertySupport.ExtractPropertyName(_PropertyExpression));
    }
    受保护的void raiseProperty已更改(字符串_Prop)
    {
    PropertyChangedEventHandler处理程序=this.PropertyChanged;
    if(处理程序!=null)
    {
    处理程序(此,新属性changedeventargs(_Prop));
    }
    }
    #端区
    }
    
    请注意,
    PropertySupport
    是Prism的一部分,但是您可以通过调用
    RaisePropertyChanged(“FilePath”)
    来取消它,具有类型安全性是很好的,因为如果更改属性的名称,将出现编译时错误。

    不要复制数据

    首选
    Binding
    IValueConverter
    ,因为这样,每当
    FilePath
    更改时,
    扩展名和
    文件名也会在UI中更新

    当然,您也可以在
    文件路径
    的setter中为他们提出
    属性更改
    ,但这是一种不好的做法,因为
    文件路径
    不必关心谁/什么人使用它

    然后,该类看起来像:

    public class VideoFile : INotifyPropertyChanged {
    
        string m_FilePath;
        public string FilePath 
        { 
           get { return m_FilePath; } 
           protected set
           {
              if(value != m_FilePath)
              {
                 m_FilePath = value;
                 RaisePropertyChanged(() => this.FilePath);
              }
           }
        }
        public uint ID { get; protected set; }
    
        #region INotifyPropertyChanged Members
    
        public event PropertyChangedEventHandler PropertyChanged;
        protected void RaisePropertyChanged<T>(Expression<Func<T>> _PropertyExpression)
        {
            RaisePropertyChanged(PropertySupport.ExtractPropertyName(_PropertyExpression));
        }
    
        protected void RaisePropertyChanged(String _Prop)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(_Prop));
            }
        }
    
        #endregion
    }
    
    公共类视频文件:INotifyPropertyChanged{
    字符串m_文件路径;
    公共字符串文件路径
    { 
    获取{return m_FilePath;}
    保护集
    {
    if(值!=m_文件路径)
    {
    m_FilePath=值;
    RaisePropertyChanged(()=>this.FilePath);
    }
    }
    }
    公共uint ID{get;protected set;}
    #区域INotifyProperty更改成员
    公共事件属性更改事件处理程序属性更改;
    受保护的void RaisePropertyChanged(表达式_PropertyExpression)
    {
    RaisePropertyChanged(PropertySupport.ExtractPropertyName(_PropertyExpression));
    }
    受保护的void raiseProperty已更改(字符串_Prop)
    {
    PropertyChangedEventHandler处理程序=this.PropertyChanged;
    if(处理程序!=null)
    {
    处理程序(此,新属性changedeventargs(_Prop));
    }
    }
    #端区
    }
    

    请注意,
    PropertySupport
    是Prism的一部分,但是您可以通过调用
    RaisePropertyChanged(“FilePath”)
    而不使用它,具有类型安全性是很好的,因为如果您更改属性的名称,将出现编译时错误。

    据我所知,您只想在UI上显示文件名。然后,您可以考虑在文件路径依赖性属性更改时更新文件名属性(OnCudiDeFielPATH方法)。您还可以在ValidateFilePath方法中检查FilePath是否正常。请注意,文件名还必须是一个依赖项属性或支持IPropertyChanged,否则更改时UI将不会更新。您不需要为此目的使用转换器

    public string FilePath
    {
        get { return (string)GetValue(FilePathProperty); }
        set { SetValue(FilePathProperty, value); }
    }
    
    private static object CoerceFilePath(DependencyObject d, object value)
    {
        return value;
    }
    
    private static bool ValidateFilePath(object Value)
    {
        return true;
    }
    
    private static void OnChangedFilePath(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
    }
    
    public static readonly DependencyProperty FilePathProperty =
        DependencyProperty.Register("FilePath", typeof(string), typeof(ClassName),
        new PropertyMetadata(@"C:\File.avi", OnChangedFilePath, CoerceFilePath),
        new ValidateValueCallback(ClassName.ValidateFilePath));
    

    据我所知,您只想在UI上显示文件名。然后,您可以考虑在文件路径依赖性属性更改时更新文件名属性(OnCudiDeFielPATH方法)。您还可以在ValidateFilePath方法中检查FilePath是否正常。请注意,文件名还必须是一个依赖项属性或支持IPropertyChanged,否则更改时UI将不会更新。您不需要为此目的使用转换器

    public string FilePath
    {
        get { return (string)GetValue(FilePathProperty); }
        set { SetValue(FilePathProperty, value); }
    }
    
    private static object CoerceFilePath(DependencyObject d, object value)
    {
        return value;
    }
    
    private static bool ValidateFilePath(object Value)
    {
        return true;
    }
    
    private static void OnChangedFilePath(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
    }
    
    public static readonly DependencyProperty FilePathProperty =
        DependencyProperty.Register("FilePath", typeof(string), typeof(ClassName),
        new PropertyMetadata(@"C:\File.avi", OnChangedFilePath, CoerceFilePath),
        new ValidateValueCallback(ClassName.ValidateFilePath));
    

    对此,您不需要
    dependencProperties
    。当你是g时,你只需要一个
    dependencProperty