131 messaggi dal 12 febbraio 2001
Salve,

ho creato uno usercontrol con un button che all'evento click imposta a visibility.hidden lo usercontrol stesso.
Spesso quando clicco sul bottone si verifica il seguente errore:

Valore non compreso nell'intervallo previsto.
su MS.Internal.XcpImports.MethodEx(IntPtr ptr, String name, CValue[] cvData)
su MS.Internal.XcpImports.MethodPack(IntPtr objectPtr, String methodName, Object[] rawData)
su MS.Internal.XcpImports.MouseEventArgs_GetPosition(MouseEventArgs args, UIElement relativeTo)
su System.Windows.Input.MouseEventArgs.GetPosition(UIElement relativeTo)
su System.Windows.Controls.Primitives.ButtonBase.OnMouseMove(MouseEventArgs e)
su System.Windows.Controls.Control.OnMouseMove(Control ctrl, EventArgs e)
su MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, String

il codice xaml del button è questo:

<Button x:Name="CloseButton" Height="35" Margin="0,0,0,0" Opacity="1"
VerticalAlignment="Center" HorizontalAlignment="Right" Width="35" Grid.Column="1" Cursor="Hand" Click="CloseMW" >
<Button.Template>
<ControlTemplate>
<Grid>
<vsm:VisualStateManager.VisualStateGroups>
<vsm:VisualStateGroup x:Name="CommonStates">
<vsm:VisualState x:Name="Normal">
</vsm:VisualState>
<vsm:VisualState x:Name="MouseOver">
<Storyboard x:Name="AnimCloseButton" RepeatBehavior="1x" AutoReverse="False">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Croce" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="30"/>
<SplineDoubleKeyFrame KeyTime="00:00:00.1000000" Value="90"/>
<SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="150"/>
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="210"/>
<SplineDoubleKeyFrame KeyTime="00:00:00.4000000" Value="270"/>
<SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="330"/>
<SplineDoubleKeyFrame KeyTime="00:00:00.6000000" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
</vsm:VisualStateGroup>
</vsm:VisualStateManager.VisualStateGroups>
<Ellipse Fill="Transparent" Height="30" Width="30" StrokeThickness="3" Stroke="White" />
<Canvas Width="3" Height="25.5" x:Name="Croce" RenderTransformOrigin="0.5,0.5" Cursor="Hand">
<Canvas.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1"/>
<SkewTransform AngleX="0" AngleY="0"/>
<RotateTransform Angle="0"/>
<TranslateTransform X="0" Y="0"/>
</TransformGroup>
</Canvas.RenderTransform>
<Path RenderTransformOrigin="0.5,0.5" Width="3" Height="25.5" Fill="Transparent" Stretch="Fill" Stroke="#FFFFFFFF" StrokeThickness="3" Data="M271.25,83.75 L271.25,106.25">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1"/>
<SkewTransform AngleX="0" AngleY="0"/>
<RotateTransform Angle="45"/>
<TranslateTransform X="0" Y="0"/>
</TransformGroup>
</Path.RenderTransform>
</Path>
<Path Width="3" Height="25.5" Fill="Transparent" Stretch="Fill" Stroke="#FFFFFFFF" StrokeThickness="3" Data="M271.25,83.75 L271.25,106.25" RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1"/>
<SkewTransform AngleX="0" AngleY="0"/>
<RotateTransform Angle="-45"/>
<TranslateTransform X="0" Y="0"/>
</TransformGroup>
</Path.RenderTransform>
</Path>
</Canvas>
</Grid>
</ControlTemplate>
</Button.Template>
</Button>

CRedo che il problema sia causato dall'animazione associata allo stato MouseOver. Se cosi fosse, come faccio da codice, ad interrompere l'animazione prima di impostare la visibility a collapsed?
Se invece il motivo non è questo qualcuno sa darm i qualche suggerimento sul motivo dell'eccezione?

Grazie

Edika
2.190 messaggi dal 04 marzo 2004
Contributi | Blog
edika wrote:
Salve,

ho creato uno usercontrol con un button che all'evento click imposta a visibility.hidden lo usercontrol stesso.
..
CRedo che il problema sia causato dall'animazione associata allo stato MouseOver. Se cosi fosse, come faccio da codice, ad interrompere l'animazione prima di impostare la visibility a collapsed?
Se invece il motivo non è questo qualcuno sa darm i qualche suggerimento sul motivo dell'eccezione?
Ciao,
la tua intuizione sembrerebbe corretta, tuttavia ho fatto alcune prove e non riesco a replicare l'eccezione, io nel gestore dell'evento Click sto usando: private void CloseMW(object sender, RoutedEventArgs e)
{
this.Visibility = Visibility.Collapsed;
}
tu?

Alessio Leoncini (WinRTItalia.com)
.NET Developer, Interactive Designer, UX Specialist, Trainer
131 messaggi dal 12 febbraio 2001
Ciao,

in realta all'evento click imposto a visibility.collapsed il contenitore dello usercontrol.
Questo user control viene caricato dinamicamente e visualizzato come fosse una modal window. In realta è solo all'interno di una grid vuota al di sopra di tuti gli altri elementi di Page.
All'evento click imposto la grid contenitore a visibility.collapsed e dalla Page distruggo lo usercontrol chiamando Dispose (implementa IDisposable perche devo finalizzare alcuni timer e sottoscrizioni ad eventi).
La Page contenitore è circa cosi:

<Grid x:Name="LayoutRoot" Background="White">
<Grid x:Name="AppContent">
<TextBlock Text="AppContent" HorizontalAlignment="Center"/>
</Grid>
<Grid x:Name="ModalWindow" Visibility="Collapsed">
<Grid x:Name="LightBox" Background="DimGray" Opacity="0.8" Visibility="Visible">
</Grid>
<Grid x:Name="MWContent" Margin="5,5,5,5"></Grid>
</Grid>
</Grid>

Lo usercontrol lo carico da page in MWContent ed imposto ModalWindow a visbility.visible
Quando clicco sul bottone di chiusura imposto dallo usercontrol MoadalWndow.visibilita=collapsed e chiamo un evento che avverte page che lo usercontrol ora è nascosto. A questo punto da Page chiamo dispose dello usercontrol e Children.Clear di MWContent

Il codice del button.click è questo

private void CloseMW(object sender, RoutedEventArgs e)
{
try
{
var ModalWindow = (Grid)Utility.getElement(this, "ModalWindow");
ModalWindow.Visibility = System.Windows.Visibility.Collapsed;
}
catch (Exception ex)
{
Logger.LogError(ex);
}
finally
{
if (_timer != null)
_timer.Stop();
_timer = null;
Raise_Close();
}
}

e questo il codice Page all'evento close dello usercontrol:

void MyControl_OnClose(object sender, EventArgs e)
{
MyControl f = sender as MyControl;
if (f != null) f.Dispose();
Grid content = (Grid)Utility.getElement(this, "MWContent");
content.Children.Clear();
}

Spero questo possa aiutarti a ripordurre l'eccezione.
Grazie

Edika
2.190 messaggi dal 04 marzo 2004
Contributi | Blog
Penso che il Dispose tolga "sotto i piedi" l'oggetto durante l'animazione, causando l'eccezione. Lo suppongo ma non ne sono certo.

Per raggiungere lo Storyboard devi "scavare" un po' nel tree dell controllo: private void CloseMW(object sender, RoutedEventArgs e) {
Button button = sender as Button;
FrameworkElement elem = FindVisualChild<FrameworkElement>(button);
IList groups = VisualStateManager.GetVisualStateGroups(elem);
foreach (VisualStateGroup vsg in groups)
{
foreach (VisualState vs in vsg.States)
{
Storyboard s1 = vs.Storyboard;
}
}
}

private childItem FindVisualChild<childItem>(DependencyObject obj) where childItem : DependencyObject
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) {
DependencyObject child = VisualTreeHelper.GetChild(obj, i); if (child != null && child is childItem)
return (childItem)child;
else
{
childItem childOfChild = FindVisualChild<childItem>(child); if (childOfChild != null)
return childOfChild;
}
}
return null;
}

Potresti prendere spunto ed esporre lo Storyboard come proprietà dell'UserControl invece di cercarlo in un evento. Forse risolvi, anche se credo si possano avere soluzioni migliori.

Alessio Leoncini (WinRTItalia.com)
.NET Developer, Interactive Designer, UX Specialist, Trainer
131 messaggi dal 12 febbraio 2001
Grazie Alessio,

per adesso ho tolto l'animazione, e aspetto SL3 e Blend 3 per avere pieno supporto del VisualStateManager...tutto questo codice per un bottoncino animato mi sembra davvero troppo....

Edika
2.190 messaggi dal 04 marzo 2004
Contributi | Blog
edika ha scritto:
Grazie Alessio,

per adesso ho tolto l'animazione, e aspetto SL3 e Blend 3 per avere pieno supporto del VisualStateManager...tutto questo codice per un bottoncino animato mi sembra davvero troppo....

Edika

In un Custom control effettivamente tutto sarebbe più conciso:
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
StoryBoard s = GetTemplateChild("AnimCloseButton") as StoryBoard ;
}
Sicuro di risolvere con Silverlight 3.0 ?

Alessio Leoncini (WinRTItalia.com)
.NET Developer, Interactive Designer, UX Specialist, Trainer
131 messaggi dal 12 febbraio 2001
Ciao,

questa mattina si è verificato nuovamente l'errore nonostante abbia tolto l'animazione. A questo punto non capisco che cosa possa provocare questa eccezione, e sopratutto perche è l'evento MouseMove quello da cui parte tutto, visto che non ho associato alcuna azione a questo evento.

Edika
2.190 messaggi dal 04 marzo 2004
Contributi | Blog
edika wrote:
Ciao,

questa mattina si è verificato nuovamente l'errore nonostante abbia tolto l'animazione. A questo punto non capisco che cosa possa provocare questa eccezione, e sopratutto perche è l'evento MouseMove quello da cui parte tutto, visto che non ho associato alcuna azione a questo evento.
Sai, effettivamente l'evento cmq si verifica anche senza animazione; io credo che questo comportamento anomalo (dettato dal fatto che non si verifica sempre) sia causato dalla forzatura che applichi richiamando il metodo Dispose. Sicuro di averne realmente bisogno? In fondo quando fai content.Children.Clear(); stacchi tutti gli oggetti dalla gerarchia e lasci gestire il loro ciclo di vita al Garbage Collector.

Alessio Leoncini (WinRTItalia.com)
.NET Developer, Interactive Designer, UX Specialist, Trainer

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.