• c# wpf自定义控件


    需要继承System.Windows.Controls.UserControl类

    使用System.Windows.DependencyProperty绑定属性

    注意在自定义控件中 不要设置DataContext 默认就行 否则的话我们使用定义好的自定义控件时,使用动态绑定无效

    我们如果使用其他类 可以在我们自定义的UserControl内部的控件上绑定DataContext

    MyControl后台类

    namespace MyApp.Component
    {
        public partial class MyControl : UserControl
        {
            // 这里控件属性的定义也可以放到一个实体类中  实体类需要继承DependencyObject
            // 在这里实例化这个实体类,并在绑定(SetBinding)的时候 把Source 设置为这个实体类的对象
            // 建议直接放到自定义控件类内部,因为这些字段需要提供给使用者传入
            // DependencyProperty暂时不知道怎么回事,无法在页面绑定 只能在在后台使用SetBinding绑定
            // 页面上绑定数据 可以新建一个实体类 实现INotifyPropertyChanged
            private static readonly VideoData VideoData = new VideoData();
            public string MediaUrl
            {
                set => SetValue(MediaUrlProperty, value);
                get => (string)GetValue(MediaUrlProperty);
            }
            
            public string Poster
            {
                set => SetValue(PosterProperty, value);
                get => (string)GetValue(PosterProperty);
            }
    
            public bool IsAudio
            {
                set => SetValue(IsAudioProperty, value);
                get => (bool)GetValue(IsAudioProperty);
            }
            
            public static readonly DependencyProperty MediaUrlProperty = DependencyProperty.Register("MediaUrl", typeof(string), typeof(VideoControl),
                new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.None, (sender, args) => 
                {
                    if (args.NewValue != null)
                    {
                        //MediaUrl值改变
                        ((MyControl)sender).VlcControl.SourceProvider.MediaPlayer.Play(new Uri(args.NewValue.ToString()), new string[] { });
                    }
                })
            );
            
            public static readonly DependencyProperty PosterProperty = DependencyProperty.Register(nameof(Poster), typeof(string), typeof(VideoControl),
                new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.None, (sender, args) => 
                {
                    if (args.NewValue != null)
                    {
                        VideoData.Poster = args.NewValue as string;
                    }
                })
            );
    
            public static readonly DependencyProperty IsAudioProperty = DependencyProperty.Register(nameof(IsAudio), typeof(bool), typeof(VideoControl),
                new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.None, (sender, args) => 
                {
                    //bool 只能取值true和false 所以这里默认值不能设置为空 
                    //这里默认值为false 所以这里初始化时控件传递过来的是false 这里就不执行了
                    //所以需要对我们需要控制的属性设置好默认值,防止属性被其他页面更改为true,另一个页面初始化时传递的是false
                    //这里就不会被执行导致实际和预期的属性值不一样,导致程序出现bug
                    //注意这里VideoData定义为静态的 
                    //注意这里需要注意 VideoData.IsAudio 初始化时一定要是false
                    VideoData.IsAudio = (bool)args.NewValue;
                })
            );
            
            public MyControl()
            {
                //!DesignerProperties.GetIsInDesignMode(this)
                //为了处理引入该控件预览问题
                if (DesignerProperties.GetIsInDesignMode(this))
                {
                    //设计模式什么也不处理  主要处理预览出错问题
                    //这么处理的话不影响引入该控件页面其他位置的预览
                    //就是当前控件被引入时预览时不显示 只显示一个框框
                    return;
                }
                
                //运行模式才进行处理
                InitializeComponent();
                //在后台绑定  (我在前台页面绑定不生效,不知道什么原因,可能时我的使用姿势不对)
                //这里把视频的地址绑定到Tag上 在回调地方把控件的视频地址修改了
                //VlcControl.SetBinding(Vlc.DotNet.Wpf.VlcControl.TagProperty, new Binding("MediaUrl") { Source = this });
                //nameof(MediaUrl) 等同于 "MediaUrl"
                VlcControl.SetBinding(Vlc.DotNet.Wpf.VlcControl.TagProperty, new Binding(nameof(MediaUrl)) { Source = this });
                //注意不要设置 DataContext = VideoData 否则DependencyProperty 值改变事件无法生效
                //VideoData 是静态的每次实例化时需要设置默认值 和 IsAudioProperty 的默认值对应 
                //否则可能出现问题
                VideoData.IsAudio = false;
                RootLayout.DataContext = VideoData
            }
            
            private void UserControl_Loaded(object sender, RoutedEventArgs e)
            {
                //加载初始化
            }
            
            private void UserControl_Unloaded(object sender, RoutedEventArgs e)
            {
                //结束清理资源
            }
            
        }
    }

    VideoData类

    namespace MyApp.custom
    {
        internal class VideoData : INotifyPropertyChanged
        {
            private bool _isPlaying;
            private string _formatShow;
            private bool _isFullscreen;
            private bool _isStart;
            private bool _isLoaded;
            private string _poster; // 视频封面图
            private bool _isAudio;
            private string _videoPath; //当前正在播放的音视频地址
            private bool _isSeekable;
    ​
            public bool IsPlaying
            {
                set
                {
                    _isPlaying = value;
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("IsPlaying"));
                }
    ​
                get => _isPlaying;
            }
    ​
            public string FormatShow
            {
                set
                {
                    _formatShow = value;
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("FormatShow"));
                }
    ​
                get => _formatShow;
            }
    ​
            public bool IsFullscreen
            {
                set
                {
                    _isFullscreen = value;
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("IsFullscreen"));
                }
                get => _isFullscreen;
            }
    ​
            public bool IsStart
            {
                set
                {
                    _isStart = value;
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("IsStart"));
                }
                get => _isStart;
            }
    ​
            public bool IsLoaded
            {
                set
                {
                    _isLoaded = value;
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("IsLoaded"));
                }
    ​
                get => _isLoaded;
            }
            
           public string Poster
            {
                set
                {
                    _poster = value;
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("poster"));
                }
                get => _poster;
            }
            
            public bool IsAudio
            {
                set
                {
                    _isAudio = value;
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("IsAudio"));
                }
    ​
                get => _isAudio;
            }
    ​
            public string VideoPath
            {
                set
                {
                    _videoPath = value;
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("VideoPath"));
                }
    ​
                get => _videoPath;
            }
    ​
            public bool IsSeekable 
            {
                set
                {
                    _isSeekable = value;
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("IsSeekable"));
                }
    ​
                get => _isSeekable;
            }
            public event PropertyChangedEventHandler PropertyChanged;
        }
    }

     

    MyControl.xaml 前台页面

    <UserControl x:Class="MyApp.custom.MyControl"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:MyApp"
                 xmlns:res="clr-namespace:MyApp.Properties"
                 xmlns:vlc="clr-namespace:Vlc.DotNet.Wpf;assembly=Vlc.DotNet.Wpf" 
                 mc:Ignorable="d" 
                 Loaded="UserControl_Loaded"
                 Unloaded="UserControl_Unloaded"
                 d:DesignHeight="675" d:DesignWidth="1200">
        
        <Grid x:Name="RootLayout">
            <vlc:VlcControl Name="VlcControl"></vlc:VlcControl>
            <!--视频封面-->
            <Grid>
                <Image Stretch="Fill" Name="PosterImage">
                    <Image.Style>
                        <Style TargetType="Image">
                            <Setter Property="Source" Value="{Binding Poster}" />
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding Poster}" Value="{x:Null}">
                                    <Setter Property="Source" Value="{x:Null}" />
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </Image.Style>
                </Image>
            </Grid>
        </Grid>
        
    </UserControl>

    使用MyControl

    <Page x:Class="MyApp.ui.VideoPage"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
          xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
          xmlns:local="clr-namespace:MyApp"
          xmlns:res="clr-namespace:MyApp.Properties"
          xmlns:my="clr-namespace:MyApp.custom"
          mc:Ignorable="d" 
          Loaded="Page_Loaded"
          d:DesignHeight="1080" d:DesignWidth="1920"
          Title="视频测试">
        <Grid>
            <!--可以使用Binding动态绑定
            如果自定义控件MyControl 设置了DataContext = xxxx则无法使用动态绑定
            -->
            <my:MyControl MediaUrl="视频地址"></my:MyControl>
        </Grid>
    </Page>

     

  • 相关阅读:
    鼠标放上面有提示
    js-行事件
    angularjs----实现切换,显示隐藏,选中一行不是table
    [2015-10-28]点击隐藏和显示-jquery和样式
    [2015-10-28]Angularjs-----数据获取,关联
    [2015-10-28]表格排序----question
    [2015-10-27]前端导出excel
    Kafka设计解析(一)- Kafka背景及架构介绍
    JAVA加解密
    kafka入门
  • 原文地址:https://www.cnblogs.com/rchao/p/15221630.html
Copyright © 2020-2023  润新知