C# 将对象传递给将控制它的UserControl
我试图将在C# 将对象传递给将控制它的UserControl,c#,wpf,user-controls,C#,Wpf,User Controls,我试图将在main窗口中创建的对象传递给我的UserControl,该控件将读取和修改它,但它不知道为什么。以下是我正在使用的代码: main窗口class: public partial class MainWindow : Window { public SupremeLibrary.Player player = new SupremeLibrary.Player(); public MainWindow() { InitializeCompone
main窗口中创建的对象
传递给我的UserControl
,该控件将读取和修改它,但它不知道为什么。以下是我正在使用的代码:
main窗口
class:
public partial class MainWindow : Window
{
public SupremeLibrary.Player player = new SupremeLibrary.Player();
public MainWindow()
{
InitializeComponent();
MusicSeekBar = new Components.SeekBar(player);
}
}
和SeekBar
用户控件:
public partial class SeekBar : UserControl
{
DispatcherTimer Updater = new DispatcherTimer();
SupremeLibrary.Player player;
/// <summary>
/// Initialize new Seekbar
/// </summary>
public SeekBar()
{
InitializeComponent();
InitializeUpdater();
}
public SeekBar(SupremeLibrary.Player _player)
{
player = _player;
InitializeComponent();
InitializeUpdater();
}
private void InitializeUpdater()
{
Updater.Interval = TimeSpan.FromMilliseconds(100);
Updater.Tick += UpdateSeekBar;
Updater.Start();
}
private void UpdateSeekBar(object sender, EventArgs e)
{
if (player != null)
{
if (player.PlaybackState == SupremeLibrary.PlaybackStates.Playing)
{
if (player.Position.TotalMilliseconds != CustomProgressBar.Value) CustomProgressBar.Value = player.Position.TotalMilliseconds;
if (player.MaxPosition.TotalMilliseconds != CustomProgressBar.Maximum) CustomProgressBar.Maximum = player.MaxPosition.TotalMilliseconds;
}
}
}
private void PB_SeekBar_ChangeValue(object obj, MouseEventArgs e)
{
if (player != null)
{
if (player.PlaybackState == SupremeLibrary.PlaybackStates.Playing)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
player.Position = TimeSpan.FromMilliseconds(e.GetPosition(obj as ProgressBar).X / ((obj as ProgressBar).ActualWidth / 100) * ((obj as ProgressBar).Maximum / 100));
}
}
}
}
作为静态,在UserControl
asmain window.player中调用它,但它很难看,我不想使用它
我试图将main窗口中的player
作为参考传递,但似乎也不起作用。使用MediaElement的示例
用户控制SeekBar
XAML
我已经在控件中定义了一个滑块,该滑块绑定到控件的最大值和值属性TotalMillicles和CurrentPosition,这些属性将绑定到控件本身,因为我已经将控件的DataContext设置为self
.cs
public分部类SeekBar:UserControl
{
DispatcherTimer Updater=新DispatcherTimer();
///
///初始化新Seekbar
///
公共SeekBar()
{
初始化组件();
初始化pdater();
}
私有无效初始化更新()
{
Updater.Interval=TimeSpan.From毫秒(100);
Updater.Tick+=UpdateSeekBar;
}
公共媒体播放器
{
get{return(MediaElement)GetValue(PlayerProperty);}
set{SetValue(PlayerProperty,value);}
}
//使用DependencyProperty作为播放器的后台存储。这将启用动画、样式、绑定等。。。
公共静态只读从属属性PlayerProperty=
DependencyProperty.Register(“播放器”、类型化(MediaElement)、类型化(SeekBar)、新属性元数据(null、OnPlayerChanged));
PlayerChanged上的私有静态无效(DependencyObject d、DependencyPropertyChangedEventArgs e)
{
SeekBar seekB=d作为SeekBar;
如果(e.OldValue!=null)
{
SeekBar oldSeekB=(e.OldValue为SeekBar);
oldsekb.Player.mediaopend-=seekB.Player\u mediaopend;
oldSeekB.Player.MediaEnded-=seekB.Player\u MediaEnded;
}
if(seekB.Player!=null)
{
seekB.Player.mediaopend+=seekB.Player\u mediaopend;
seekB.Player.MediaEnded+=seekB.Player\u MediaEnded;
}
}
无效播放器(对象发送器,路由目标e)
{
Updater.Stop();
}
私有void Player_media已打开(对象发送器,路由目标e)
{
if(玩家.自然适应.黑斯密斯潘)
{
TotalMillistics=Player.NaturalDuration.TimeSpan.TotalMillistics;
Updater.Start();
}
其他的
{
当前位置=0.0;
总毫秒=1.0;
}
}
公共双电流位置
{
获取{return(double)GetValue(CurrentPositionProperty);}
set{SetValue(CurrentPositionProperty,value);}
}
//使用DependencyProperty作为CurrentPosition的后备存储。这将启用动画、样式、绑定等。。。
公共静态只读从属属性CurrentPositionProperty=
DependencyProperty.Register(“CurrentPosition”、typeof(double)、typeof(SeekBar)、新PropertyMetadata(1.0,OnCurrentPositionChange));
当前位置更改时的私有静态无效(DependencyObject d、DependencyPropertyChangedEventArgs e)
{
SeekBar seekB=d作为SeekBar;
if(seekB.Player!=null)
{
seekB.Player.Position=TimeSpan.From毫秒(seekB.CurrentPosition);
}
}
公共双总毫秒
{
获取{return(double)GetValue(totalmillissecondsproperty);}
set{SetValue(totalmillissecondsproperty,value);}
}
//使用DependencyProperty作为Total毫秒的备份存储。这将启用动画、样式、绑定等。。。
公共静态只读从属属性Total毫秒属性=
dependencProperty.Register(“totalmillizes”、typeof(double)、typeof(SeekBar)、newpropertyMetadata(0.0));
私有void UpdateSeekBar(对象发送方,事件参数e)
{
if(Player!=null&&totalmillizes>1)
{
CurrentPosition=Player.Position.total毫秒;
}
}
}
我所做的
- 要在UI上绑定的媒体元素的已定义属性Player
- 连接的媒体已打开,媒体已结束,用于启动和停止计时器以及更新持续时间
- 控件UI中滑块控件的当前位置和总持续时间的定义属性
- 当当前位置改变时,我会更新玩家的位置
主窗口中的用法
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<MediaElement x:Name="media"
Source="Wildlife.wmv" />
<l:SeekBar Grid.Row="1"
Player="{Binding ElementName=media}" />
</Grid>
我将把媒体元素绑定到SeekBar控件的Player属性
通过这种方式,我没有在代码隐藏中进行任何硬编码,同样通过接口,您可以在seekbar和播放器之间实现更大的解耦
这只是一个简单的示例,您可以在上面的示例中使用自定义播放机和进度控制来实现您的结果。SupremeLibrary.player支持数据绑定吗?这就是全部代码。它是wpf,所以我想soSupremeLibrary看起来不像.net框架的一部分。所以我不能这样假设。如果我在互联网上搜索,我无法找到相关的图书馆。那么,你能给我一个相同的链接,或者只是确认是否支持绑定。我创建了那个库。基本上有MediaPlayer控件。那么数据绑定对您来说是一种很好的方法,而不是将播放器传递给控件,而是利用datacontext。
<UserControl x:Class="CSharpWPF.SeekBar"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
DataContext="{Binding RelativeSource={RelativeSource Self}}" >
<Slider Maximum="{Binding TotalMilliseconds}"
Value="{Binding CurrentPosition}"/>
</UserControl>
public partial class SeekBar : UserControl
{
DispatcherTimer Updater = new DispatcherTimer();
/// <summary>
/// Initialize new Seekbar
/// </summary>
public SeekBar()
{
InitializeComponent();
InitializeUpdater();
}
private void InitializeUpdater()
{
Updater.Interval = TimeSpan.FromMilliseconds(100);
Updater.Tick += UpdateSeekBar;
}
public MediaElement Player
{
get { return (MediaElement)GetValue(PlayerProperty); }
set { SetValue(PlayerProperty, value); }
}
// Using a DependencyProperty as the backing store for Player. This enables animation, styling, binding, etc...
public static readonly DependencyProperty PlayerProperty =
DependencyProperty.Register("Player", typeof(MediaElement), typeof(SeekBar), new PropertyMetadata(null, OnPlayerChanged));
private static void OnPlayerChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
SeekBar seekB = d as SeekBar;
if (e.OldValue != null)
{
SeekBar oldSeekB = (e.OldValue as SeekBar);
oldSeekB.Player.MediaOpened -= seekB.Player_MediaOpened;
oldSeekB.Player.MediaEnded -= seekB.Player_MediaEnded;
}
if (seekB.Player != null)
{
seekB.Player.MediaOpened += seekB.Player_MediaOpened;
seekB.Player.MediaEnded += seekB.Player_MediaEnded;
}
}
void Player_MediaEnded(object sender, RoutedEventArgs e)
{
Updater.Stop();
}
private void Player_MediaOpened(object sender, RoutedEventArgs e)
{
if (Player.NaturalDuration.HasTimeSpan)
{
TotalMilliseconds = Player.NaturalDuration.TimeSpan.TotalMilliseconds;
Updater.Start();
}
else
{
CurrentPosition = 0.0;
TotalMilliseconds = 1.0;
}
}
public double CurrentPosition
{
get { return (double)GetValue(CurrentPositionProperty); }
set { SetValue(CurrentPositionProperty, value); }
}
// Using a DependencyProperty as the backing store for CurrentPosition. This enables animation, styling, binding, etc...
public static readonly DependencyProperty CurrentPositionProperty =
DependencyProperty.Register("CurrentPosition", typeof(double), typeof(SeekBar), new PropertyMetadata(1.0, OnCurrentPositionChange));
private static void OnCurrentPositionChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
SeekBar seekB = d as SeekBar;
if (seekB.Player != null)
{
seekB.Player.Position = TimeSpan.FromMilliseconds(seekB.CurrentPosition);
}
}
public double TotalMilliseconds
{
get { return (double)GetValue(TotalMillisecondsProperty); }
set { SetValue(TotalMillisecondsProperty, value); }
}
// Using a DependencyProperty as the backing store for TotalMilliseconds. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TotalMillisecondsProperty =
DependencyProperty.Register("TotalMilliseconds", typeof(double), typeof(SeekBar), new PropertyMetadata(0.0));
private void UpdateSeekBar(object sender, EventArgs e)
{
if (Player != null && TotalMilliseconds > 1)
{
CurrentPosition = Player.Position.TotalMilliseconds;
}
}
}
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<MediaElement x:Name="media"
Source="Wildlife.wmv" />
<l:SeekBar Grid.Row="1"
Player="{Binding ElementName=media}" />
</Grid>