UIElement의 MouseEnter 및 MouseLeave 이벤트를 처리하는 WPF 첨부 동작이 있습니다. WeakEventManager를 사용하도록 전환하여 메모리 누수를 방지하려고 시도했지만 이제는 코드가 더 이상 이벤트를 처리하지 않습니다. 내가 사용하는 경우WeakEventManager가 연결된 동작에서 이벤트를 처리하지 못합니다.
(아래 참조) :
_control.MouseEnter += OnMouseEnter;
_control.MouseLeave += OnMouseLeave;
코드가 이벤트를 처리합니다. 내가 사용하는 경우
(아래 참조) :
이WeakEventManager<UIElement, RoutedEventArgs>.AddHandler(_control, "MouseEnter", OnMouseEnter);
WeakEventManager<UIElement, RoutedEventArgs>.AddHandler(_control, "MouseLeave", OnMouseLeave);
코드가 이벤트를 처리하지 않습니다.
첨부 된 동작에서 WeakEventManager를 사용하여 이벤트를 처리하려면 어떻게해야합니까?
다음은 XAML에서 연결된 동작을 사용하는 방법의 예입니다. 이 경우 두 컨트롤은 TreeView 컨트롤에 노드로 나타납니다. 나는 많은 다른 컨트롤과 연결된 동작을 사용했지만 작동하지 않습니다. 여기
<HierarchicalDataTemplate x:Key="EquipmentUnitTemplate" >
<StackPanel
Orientation="Horizontal">
<controls:EquipmentUnitBillboard
Width="22"
Height="20"
VerticalAlignment="Center"
Style="{DynamicResource TreeViewNavigatorEquipmentUnitBillboardStyle}"
behaviours:ToolTipEquipmentUnitHelper.TooltipMemberBinding="{Binding EquipmentUnitModel}"
behaviours:ContextMenuEquipmentUnitHelper.ContextMenuMemberBinding="{Binding EquipmentUnitModel}"
Visibility="{Binding HasIcon, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverterCollapsed}}"
IconType="{Binding IconId, Mode=OneWay}"/>
<Label
Margin="5,0,0,0"
Padding="0,0,0,0"
VerticalAlignment="Center"
Style="{DynamicResource LabelInTreeStyle}"
behaviours:ToolTipEquipmentUnitHelper.TooltipMemberBinding="{Binding EquipmentUnitModel}"
behaviours:ContextMenuEquipmentUnitHelper.ContextMenuMemberBinding="{Binding EquipmentUnitModel}"
Content="{Binding DisplayName}"
FontWeight="Bold"
/>
</StackPanel>
</HierarchicalDataTemplate>
제거 불필요한 대부분의 코드에 첨부 된 동작입니다 :
public class ToolTipHelper
{
private readonly UIElement _control = null;
public ToolTipHelper(UIElement control)
{
this._control = control;
}
public static readonly DependencyProperty TooltipMemberBindingProperty
= DependencyProperty.RegisterAttached("TooltipMemberBinding", typeof(object), typeof(ToolTipHelper), new PropertyMetadata(null, OnTooltipMemberBindingChanged));
public static void SetTooltipMemberBinding(DependencyObject dependencyObject, object tooltipMember)
{
dependencyObject.SetValue(TooltipMemberBindingProperty, tooltipMember);
}
public static object GetTooltipMemberBinding(DependencyObject dependencyObject)
{
return (object)dependencyObject.GetValue(TooltipMemberBindingProperty);
}
private static void OnTooltipMemberBindingChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
var control = dependencyObject as UIElement;
if (control != null)
{
if ((object)e.NewValue != null)
{
var behavior = new ToolTipHelper(control);
behavior.Attach();
}
if ((object)e.OldValue != null)
{
var behavior = new ToolTipHelper(control);
behavior.Detach();
}
}
}
private void Attach()
{
if (_control != null)
{
var container = ServiceLocator.Current.GetInstance<IUnityContainer>();
var applicationServices = container.Resolve<IApplicationServices>();
var applicationSettings = container.Resolve<IApplicationSettings>();
var realtimeObjectModel = container.Resolve<IRealtimeObjectModel>();
var kpiEngine = container.Resolve<IKPIEngine>();
var wcmSettings = container.Resolve<WencoConfigurationSettingsModel>();
var val = _control.GetValue(TooltipMemberBindingProperty);
if (val is HaulingUnit)
{
HaulingUnitToolTipViewModel huvm = new HaulingUnitToolTipViewModel(applicationServices, applicationSettings, realtimeObjectModel, wcmSettings, val as HaulingUnit);
_control.SetValue(RadToolTipService.ToolTipContentProperty, huvm);
DataTemplate template = (DataTemplate)Application.Current.FindResource("HaulingUnitTooltipTemplate");
_control.SetValue(RadToolTipService.ToolTipContentTemplateProperty, template);
}
else if (val is LoadingUnit)
{
LoadingUnitToolTipViewModel luvm = new LoadingUnitToolTipViewModel(applicationServices, applicationSettings, realtimeObjectModel, kpiEngine, wcmSettings, val as LoadingUnit);
_control.SetValue(RadToolTipService.ToolTipContentProperty, luvm);
DataTemplate template = (DataTemplate)Application.Current.FindResource("LoadingUnitTooltipTemplate");
_control.SetValue(RadToolTipService.ToolTipContentTemplateProperty, template);
}
else if (val is DrillUnit)
{
DrillUnitToolTipViewModel luvm = new DrillUnitToolTipViewModel(applicationServices, applicationSettings, realtimeObjectModel, wcmSettings, val as DrillUnit);
_control.SetValue(RadToolTipService.ToolTipContentProperty, luvm);
DataTemplate template = (DataTemplate)Application.Current.FindResource("DrillUnitTooltipTemplate");
_control.SetValue(RadToolTipService.ToolTipContentTemplateProperty, template);
}
else if (val is ScraperUnit)
{
ScraperUnitToolTipViewModel scvm = new ScraperUnitToolTipViewModel(applicationServices, applicationSettings, realtimeObjectModel, wcmSettings, val as ScraperUnit);
_control.SetValue(RadToolTipService.ToolTipContentProperty, scvm);
DataTemplate template = (DataTemplate)Application.Current.FindResource("ScraperUnitTooltipTemplate");
_control.SetValue(RadToolTipService.ToolTipContentTemplateProperty, template);
}
else if (val is AuxiliaryUnit)
{
AuxiliaryUnitToolTipViewModel auvm = new AuxiliaryUnitToolTipViewModel(applicationServices, applicationSettings, realtimeObjectModel, wcmSettings, val as AuxiliaryUnit);
_control.SetValue(RadToolTipService.ToolTipContentProperty, auvm);
DataTemplate template = (DataTemplate)Application.Current.FindResource("OtherUnitTooltipTemplate");
_control.SetValue(RadToolTipService.ToolTipContentTemplateProperty, template);
}
else if (val is FuelTruckUnit)
{
FuelTruckUnitToolTipViewModel auvm = new FuelTruckUnitToolTipViewModel(applicationServices, applicationSettings, realtimeObjectModel, wcmSettings, val as FuelTruckUnit);
_control.SetValue(RadToolTipService.ToolTipContentProperty, auvm);
DataTemplate template = (DataTemplate)Application.Current.FindResource("OtherUnitTooltipTemplate");
_control.SetValue(RadToolTipService.ToolTipContentTemplateProperty, template);
}
else if (val is CrusherUnit)
{
CrusherUnitToolTipViewModel auvm = new CrusherUnitToolTipViewModel(applicationServices, applicationSettings, realtimeObjectModel, wcmSettings, val as CrusherUnit);
_control.SetValue(RadToolTipService.ToolTipContentProperty, auvm);
DataTemplate template = (DataTemplate)Application.Current.FindResource("OtherUnitTooltipTemplate");
_control.SetValue(RadToolTipService.ToolTipContentTemplateProperty, template);
}
//else if (val is DumpLocationDispatchConfigurationViewModel)
//{
//}
int initial = Convert.ToInt32(SharedConstants.TooltipInitialShowDelayDuration.TotalMilliseconds);
_control.SetValue(RadToolTipService.InitialShowDelayProperty, initial);
int between = Convert.ToInt32(SharedConstants.TooltipBetweenShowDelayDuration.TotalMilliseconds);
_control.SetValue(RadToolTipService.BetweenShowDelayProperty, between);
int duration = Convert.ToInt32(applicationSettings.ProgramSettings.ToolTips.ToolTipOpenDuration.TotalMilliseconds);
_control.SetValue(RadToolTipService.ShowDurationProperty, duration);
// using this code the event never gets handled
WeakEventManager<UIElement, RoutedEventArgs>.AddHandler(_control, "MouseEnter", OnMouseEnter);
WeakEventManager<UIElement, RoutedEventArgs>.AddHandler(_control, "MouseLeave", OnMouseLeave);
// if I uncomment these two lines the event gets handled.
//_control.MouseEnter += OnMouseEnter;
//_control.MouseLeave += OnMouseLeave;
}
}
private void Detach()
{
if (_control != null)
{
WeakEventManager<UIElement, RoutedEventArgs>.RemoveHandler(_control, "MouseEnter", OnMouseEnter);
WeakEventManager<UIElement, RoutedEventArgs>.RemoveHandler(_control, "MouseLeave", OnMouseLeave);
//_control.MouseEnter -= OnMouseEnter;
//_control.MouseLeave -= OnMouseLeave;
}
}
private void OnMouseEnter(object sender, RoutedEventArgs routedEventArgs)
{
try
{
if ((sender is UIElement))
{
UIElement control = sender as UIElement;
}
}
catch (Exception ex)
{
}
}
private void OnMouseLeave(object sender, RoutedEventArgs routedEventArgs)
{
try
{
if ((sender is UIElement))
{
UIElement control = sender as UIElement;
}
}
catch (Exception ex)
{
}
}
}
난 당신의 코드를 붙여 복사하는 경우 - 그것은 나를 위해 잘 작동하고 핸들러가 발생합니다. 그걸 재현하려면 더 많은 정보가 필요하다. (제거한 불필요한 코드는 예를 들어 실제로 불필요하지 않다.) – Evk
감사합니다. 나는 Attach() 메소드의 코드를 도움이되고 사용법 XAML 예제에 추가했다. 아마도이 문제를 해결하는 데 도움이 될 수있는 XAML의 연결된 동작을 어떻게 사용했는지 보여 주시겠습니까? – Zamboni
당신이하는 것과 같은 방식으로 사용하지만, 어쨌든 값을 사용하지 않기 때문에 Binding을 사용하지 않습니다. (if ((object) e.NewValue! = null)'나는 그렇게하지 않습니다. 왜 어떤 값을 건네 주면 (예 :'Behaviors : ToolTipEquipmentUnitHelper.TooltipMemberBinding = "test"') 나에게 잘 돌아 간다. 문제를 재현 할 수있는 최소한의 예제를 찾아 보자. – Evk