Необходимо выдернуть UIElement
из контейнера, на время, после вернуть его обратно, нужен самый быстрый и рабочий способ.
Ранее делал так:
UIElement
от родителя, зная его тип.UIElement
от окна, возвращаю его на место предыдущему родителю зная его тип.В данном методе, есть множество недостатков, установить родителя можно быстро, но в режиме дебага, весь стек вывода закидывается исключениями, т.к. UIElement
не успевает отсоединиться от установленного мною нового родителя, и в цикле пытаюсь его вернуть обратно.
В принципе это работает, но медленно, и не совсем так как мне необходимо. Т.к. контейнер может быть любым, а его тип узнать можно, но это снова не то что мне нужно.
Вот класс UIElement
'a который необходимо переносить из одного контейнера в другое окно:
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using Yume.Controls.Extensions;
using Yume.Controls.Input;
using MediaElementBase = System.Windows.Controls.MediaElement;
namespace Yume.Controls
{
#region Parts Template
[TemplatePart(Type = typeof(MediaElementBase), Name = PART_MediaElementBase)]
[TemplatePart(Type = typeof(ContentPresenter), Name = PART_ControlPlayerContainer)]
#endregion
public class MediaElement : Control
{
#region Constructors
public MediaElement()
{
IsInDesignMode = GetValue<bool>(DesignerProperties.IsInDesignModeProperty);
}
static MediaElement()
{
var style = CreateDefaultStyles();
StyleProperty.OverrideMetadata(typeof(MediaElement), new FrameworkPropertyMetadata(style));
}
#endregion
#region Enevts
public event StateChengeded StateChanged;
public delegate void StateChengeded(object sender, MediaStateChangedEventArgs args);
#endregion
#region DependencyProperty
// Using a DependencyProperty as the backing store for SetFullScreenCommand. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SetFullScreenCommandProperty =
DependencyProperty.Register("SetFullScreenCommand", typeof(ICommand), typeof(MediaElement));
// Using a DependencyProperty as the backing store for RemoveFullScreenCommand. This enables animation, styling, binding, etc...
public static readonly DependencyProperty RemoveFullScreenCommandProperty =
DependencyProperty.Register("RemoveFullScreenCommand", typeof(ICommand), typeof(MediaElement));
// Using a DependencyProperty as the backing store for StopCommand. This enables animation, styling, binding, etc...
public static readonly DependencyProperty StopCommandProperty =
DependencyProperty.Register("StopCommand", typeof(ICommand), typeof(MediaElement));
// Using a DependencyProperty as the backing store for CloseCommand. This enables animation, styling, binding, etc...
public static readonly DependencyProperty CloseCommandProperty =
DependencyProperty.Register("CloseCommand", typeof(ICommand), typeof(MediaElement));
// Using a DependencyProperty as the backing store for PauseCommand. This enables animation, styling, binding, etc...
public static readonly DependencyProperty PauseCommandProperty =
DependencyProperty.Register("PauseCommand", typeof(ICommand), typeof(MediaElement));
// Using a DependencyProperty as the backing store for PlayCommand. This enables animation, styling, binding, etc...
public static readonly DependencyProperty PlayCommandProperty =
DependencyProperty.Register("PlayCommand", typeof(ICommand), typeof(MediaElement));
// Using a DependencyProperty as the backing store for PreviewImage. This enables animation, styling, binding, etc...
public static readonly DependencyProperty PreviewImageProperty =
DependencyProperty.Register("PreviewImage", typeof(BitmapImage), typeof(MediaElement),
new PropertyMetadata(null));
// Using a DependencyProperty as the backing store for MediaState. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MediaStateProperty =
DependencyProperty.Register("MediaState", typeof(MediaElementStates), typeof(MediaElement),
new PropertyMetadata(MediaElementStates.Stop));
// Using a DependencyProperty as the backing store for IsInDesignMode. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsInDesignModeProperty =
DependencyProperty.Register("IsInDesignMode", typeof(bool), typeof(MediaElement));
// Using a DependencyProperty as the backing store for ShowPlayerControls. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ShowPlayerControlsProperty =
DependencyProperty.Register("ShowPlayerControls", typeof(bool), typeof(MediaElement),
new PropertyMetadata(null));
// Using a DependencyProperty as the backing store for PlayerControlPosition. This enables animation, styling, binding, etc...
public static readonly DependencyProperty PlayerControlPositionProperty =
DependencyProperty.Register("PlayerControlPosition", typeof(PlayerControlPosition), typeof(MediaElement),
new PropertyMetadata(PlayerControlPosition.Bottom));
// Using a DependencyProperty as the backing store for PlayerControl. This enables animation, styling, binding, etc...
public static readonly DependencyProperty PlayerControlProperty =
DependencyProperty.Register("PlayerControl", typeof(object), typeof(MediaElement));
// Using a DependencyProperty as the backing store for Source. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SourceProperty =
DependencyProperty.Register("Source", typeof(Uri), typeof(MediaElement));
#endregion
#region Props
public BitmapImage PreviewImage
{
get => GetValue<BitmapImage>(PreviewImageProperty);
set => SetValue(PreviewImageProperty, value);
}
public MediaElementStates MediaState
{
get => GetValue<MediaElementStates>(MediaStateProperty);
set => SetValue(MediaStateProperty, value);
}
public bool IsInDesignMode
{
get => GetValue<bool>(IsInDesignModeProperty);
set => SetValue(IsInDesignModeProperty, value);
}
public bool ShowPlayerControls
{
get => GetValue<bool>(ShowPlayerControlsProperty);
set => SetValue(ShowPlayerControlsProperty, value);
}
public PlayerControlPosition PlayerControlPosition
{
get => GetValue<PlayerControlPosition>(PlayerControlPositionProperty);
set => SetValue(PlayerControlPositionProperty, value);
}
public object PlayerControl
{
get => GetValue<object>(PlayerControlProperty);
set => SetValue(PlayerControlProperty, value);
}
public Uri Source
{
get => GetValue<Uri>(SourceProperty);
set => SetValue(SourceProperty, value);
}
#endregion
#region Methods
protected virtual void OnStateChanged(object sender, MediaStateChangedEventArgs args)
{
StateChanged?.Invoke(sender, args);
MediaState = args.CurrentState;
}
protected virtual void OnStateChanged(object sender, MediaStateChangedEventArgs args, Action doAction)
{
OnStateChanged(sender, args);
doAction?.Invoke();
}
private T GetValue<T>(DependencyProperty dp)
{
return (T) GetValue(dp);
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
_baseMediaElement = _baseMediaElement ?? GetTemplateChild<MediaElementBase>(PART_MediaElementBase);
_playerControlPresenter = _playerControlPresenter ??
GetTemplateChild<ContentPresenter>(PART_ControlPlayerContainer);
PlayCommand = new RelayCommand(o => Play(),
o => MediaState == MediaElementStates.Pause ||
MediaState == MediaElementStates.Stop && Source != null);
PauseCommand = new RelayCommand(o => Pause(), o => MediaState == MediaElementStates.Play && Source != null);
StopCommand = new RelayCommand(o => Stop(),
o => MediaState == MediaElementStates.Pause || MediaState == MediaElementStates.Play ||
MediaState != MediaElementStates.Stop && Source != null && (_baseMediaElement.HasVideo ||
_baseMediaElement.HasAudio));
CloseCommand = new RelayCommand(o => Close(),
o => Source != null && _baseMediaElement.HasVideo || _baseMediaElement.HasAudio);
SetFullScreenCommand = new RelayCommand(o => this.SetFullScreen());
RemoveFullScreenCommand = new RelayCommand(o => this.RemoveFullScreen());
}
private T GetTemplateChild<T>(string templateName) where T : class
{
return GetTemplateChild(templateName) as T;
}
private static Style CreateDefaultStyles()
{
var style = new Style(typeof(MediaElement), null);
style.Setters.Add(new Setter(FlowDirectionProperty, FlowDirection.LeftToRight));
style.Seal();
return style;
}
public void Play()
{
OnStateChanged(this, new MediaStateChangedEventArgs(MediaElementStates.Play),
() => _baseMediaElement?.Play());
}
public void Pause()
{
OnStateChanged(this, new MediaStateChangedEventArgs(MediaElementStates.Pause),
() => _baseMediaElement?.Pause());
}
public void Stop()
{
OnStateChanged(this, new MediaStateChangedEventArgs(MediaElementStates.Stop),
() => _baseMediaElement?.Stop());
}
public void Close()
{
OnStateChanged(this, new MediaStateChangedEventArgs(MediaElementStates.Stop),
() => _baseMediaElement?.Close());
}
#endregion
#region TemplatePart Names
// ReSharper disable InconsistentNaming
private const string PART_MediaElementBase = "PART_MediaElementBase";
private const string PART_ControlPlayerContainer = "PART_ControlPlayerContainer";
// ReSharper restore InconsistentNaming
#endregion
#region TemplatePart Objects
private MediaElementBase _baseMediaElement;
private ContentPresenter _playerControlPresenter;
#endregion
#region MediaElement Commands
public ICommand PlayCommand
{
get => GetValue<ICommand>(PlayCommandProperty);
set => SetValue(PlayCommandProperty, value);
}
public ICommand PauseCommand
{
get => GetValue<ICommand>(PauseCommandProperty);
set => SetValue(PauseCommandProperty, value);
}
public ICommand StopCommand
{
get => GetValue<ICommand>(StopCommandProperty);
set => SetValue(StopCommandProperty, value);
}
public ICommand CloseCommand
{
get => GetValue<ICommand>(CloseCommandProperty);
set => SetValue(CloseCommandProperty, value);
}
public ICommand SetFullScreenCommand
{
get => GetValue<ICommand>(SetFullScreenCommandProperty);
set => SetValue(SetFullScreenCommandProperty, value);
}
public ICommand RemoveFullScreenCommand
{
get => GetValue<ICommand>(RemoveFullScreenCommandProperty);
set => SetValue(RemoveFullScreenCommandProperty, value);
}
#endregion
}
}
Расширяющий класс:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
// ReSharper disable SuggestVarOrType_SimpleTypes
namespace Yume.Controls.Extensions
{
public static class MediaElementExtensions
{
private static object _previewParentContainer;
public static Window SetFullScreen(this MediaElement mediaElement)
{
throw new NotImplementedException();
}
public static void RemoveFullScreen(this MediaElement mediaElement)
{
throw new NotImplementedException();
}
}
}
По моему мнению, лучшим решением может стать использование класса MediaPlayer
с реализацией собственной отрисовки видео, использования класса VideoDrawing
а так же перегруженный конструктор контрола, который в случае инициализации с применением класса MediaPlayer
будет использовать переданный объект для отрисовки. В противном случае будет инициализировать новый экземпляр данного класса, и использовать его.
Но я все еще жду каких либо предложений.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Ребят, подскажите как сделать полукруглый прогресс бар? С обычным вообще не возникает проблемНаходил только больно уж сложные, круглые примеры
Добрый день У меня возникла проблема, так как в использовании данного фреймворка я новичокЯ хотел создать самый простой и обычный task manager
Здравствуйте, скажите пожалуйста зачем и в чём удобства Converter'а в Binding'е?