Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[C#/.NET WPF] Object uit XAML benaderen via C#

Pagina: 1
Acties:

  • dtech
  • Registratie: Juni 2005
  • Laatst online: 19-09 15:37
Hallo,
ik heb een programmaatje gemaakt. Een window genaamt (gasp) Window1 met een page en nog wat zooi daar in. Nu wil ik vanuit mijn class App een van de dingen in de Page benaderen. In de class Window1 kan dit via this.NaamVanObject, maar kan dit ook vanuit de class App?

Voorbeeldje, XAML:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<Window  x:Class="ProjectNaam.Window1" KeyDown="onKeyDown">
<Page Name="Page1">

    <Page.Resources>
        <FrameworkElement Name="DateTimeKey" x:Key="dt" Tag="{x:Static s:DateTime.Now}" />
    </Page.Resources>
 
    <Viewbox>
    </Viewbox>

    <!-- All animations. -->

    <Page.Triggers>
        <EventTrigger RoutedEvent="Canvas.Loaded">
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation Name="HourAnimation" />
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Page.Triggers>

</Page>
</Window>


Met C# code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
namespace NewDramaClock
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }
        public void onKeyDown(object sender, KeyEventArgs e)
        {
            if(e.Key == Key.Escape)
            {
                Application.Current.Shutdown();
            }
            
        }
    }
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();
            this.EenMethod();
        }
        public void EenMethod()
        {
                // Window1 moet ik dus waarschijnlijk door iets vervangen
            Window1.HourAnimation.Duration = new Timespan(0,0,0,1,0,0);
                Window1.DateTimeKey.Tag = new Datime(3600);
        }

    }
}

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Niet op deze manier. Maar je kunt wel App.Windows[0] casten naar Window1. Dit zul je wel via een try/catch moeten doen, want de startup window hoeft niet geladen te blijven.

C#:
1
2
3
4
5
6
7
8
9
10
try
{
   Window1 w = App.Windows[0] as Window1;
   w.DateTimeKey.Tag = new DateTime(3600);
   ...
}
catch
{
   //window 0 kan niet worden gecast als Window1 instantie...
}


Maar waarom zou je applicatie properties van een specifieke page willen zetten? Je kunt het dan waarschijnlijk omdraaien, namelijk dat Window1 de applicatie benaderd bijvoorbeeld om een aantal instellingen op te halen (GaspApp.GetProperty(string propName) en GaspApp.SetProperty(string propName, object value)).

De methodes kun je dan vanuit al je pages gebruiken. App is vergelijkbaar met Global.Asax in asp.net en Program.Main uit classic windows applicaties.

If it isn't broken, fix it until it is..


  • dtech
  • Registratie: Juni 2005
  • Laatst online: 19-09 15:37
App.Windows[0] is waarschijnlijk wat ik nodig heb. Zo simpel kan het zijn.
Maar waarom zou je applicatie properties van een specifieke page willen zetten? Je kunt het dan waarschijnlijk omdraaien, namelijk dat Window1 de applicatie benaderd bijvoorbeeld om een aantal instellingen op te halen (GaspApp.GetProperty(string propName) en GaspApp.SetProperty(string propName, object value)).
Het probleem is dat elke keer als ik een stukje code zet in de constructer van Window1 Sharpdevelop het programma niet meer wil compilen. Ik hoopte dat op te lossen door de code in App te zetten en die Window1 te laten benaderen.
Ach ja, het is voor een simpel quick-and-dirty eenmalig te gebruiken programmaatje, als het maar werkt dus.

  • TeeDee
  • Registratie: Februari 2001
  • Laatst online: 19:52

TeeDee

CQB 241

Dan is meteen de vraag: Waarom kan er niet meer gecompileerd worden? Beter een constructieve oplossing dan een Quickfix. * TeeDee zou het naadje van de kous willen weten in zo'n geval.

Heart..pumps blood.Has nothing to do with emotion! Bored


  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Maar waarom gebruik je dan SharpDevelop? Waarom niet Visual Studio 2008 C# Express? Deze is gratis en heel wel goede support voor WPF.

Overigens is quick & dirty nooit goed, ook niet voor eenmalige programmaatjes. Goede programmeer principes behoren echt helemaal ingeslepen te zijn. In mijn ervaring blijkt namelijk dat eenmalige programmaatjes nooit eenmalig zijn, tenzij je daarna direct de code in de prullenbak gooit. Maar dat heb ik persoonlijk nog nooit zien gebeuren. Ik gooi zelf wel regelmatig code van programmeurs in de prullenbak. Structurele oplossingen kosten namelijk nooit veel meer tijd dan quick & dirty oplossingen.

If it isn't broken, fix it until it is..


  • dtech
  • Registratie: Juni 2005
  • Laatst online: 19-09 15:37
@Niemand_Anders
Visual Studio 2008 wil niet instaleren. 2003 trouwens ook niet. office 2007 trouwens ook niet. Microsoft installatieprogramma's hebben iets tegen installatie, anders zou ik zeker VSE gebruiken.
Ik denk trouwens dat ik niet heel vaak een klok nodig zal hebben die steeds sneller gaat lopen, maar verder ben ik het met je eens ;)

@TeeDee
Snap ik, brandt los.
De klok die ik gebruik is bijna 1:1 deze Enkel heb ik de starttijd vast gezet op 19:57 en het geheel in een <Window> gezet.
edit:

In volgende bericht staat eenvoudigere code die al niet werkt

De code is deze:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using System;
-- snip --

namespace NewDramaClock
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>

    public partial class Window1 : Window
    {
        
        
        public Window1()
        {
            InitializeComponent();
        }
        public void onKeyDown(object sender, KeyEventArgs e)
        {
            if(e.Key == Key.Escape)
            {
                Application.Current.Shutdown();
            }
            
        }
    }
}

Dit werkt, en werkt goed. Als ik er dit van maak complimeert hij niet meer met de volgende foutmelding:
code:
1
2
3
4
5
6
7
8
Uitzondering System.Windows.Markup.XamlParseException werd in de debugger verworpen:
Kan geen exemplaar maken van in assembly NewDramaClock, Version=1.0.3020.26950, Culture=neutral, PublicKeyToken=null gedefinieerde Window1. Het doel van een aanroep heeft een uitzondering veroorzaakt.  Fout in opmaakbestand Window1.xaml regel 1 positie 10. 

ReadRecord()
Read()
-- knip 101 dingen --
Run()
Main()

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
using System;
-- snip --

namespace NewDramaClock
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>

    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }
        public void onKeyDown(object sender, KeyEventArgs e)
        {
            if(e.Key == Key.Escape)
            {
                Application.Current.Shutdown();
            }
        }
        
        public DateTime SecondDuration = new DateTime(0,0,0,0,0,1);
        public Timer Tmr;
            
        public void ClockAdjust()
        {
            this.Tmr=new Timer();
            this.Tmr.Interval = 180000;
            this.Tmr.Start();
            this.Tmr.Elapsed+=new ElapsedEventHandler(ClockSpeedUp);
        }
        
        public void ClockSpeedUp(object sender,EventArgs eArgs)
        {
            
            if(this.Tmr.Interval == 180000)
            {
                this.Tmr.Interval = 10000;
                this.SecondDuration = new DateTime(0,0,0,0,0,0,333);
            }else
            {
                this.SecondDuration = new DateTime(this.SecondDuration.Ticks/2);
            }
            
            this.HourAnimation.Duration = new Duration(new TimeSpan(this.SecondDuration.Ticks*3600));
            this.MinuteAnimation.Duration = new Duration(new TimeSpan(this.SecondDuration.Ticks*60));
            this.SecondAnimation.Duration = new Duration(new TimeSpan(this.SecondDuration.Ticks));
        }
    }
}

[ Voor 10% gewijzigd door dtech op 08-04-2008 16:39 ]


  • dtech
  • Registratie: Juni 2005
  • Laatst online: 19-09 15:37
Iets makkelijker, want dit werkt ook al niet:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using System;
-- snip --

namespace NewDramaClock
{

    public partial class Window1 : Window
    {
        public double Speed = 1;
        public DateTime SecondDuration;
        
        public Window1()
        {
            InitializeComponent();
            this.SecondDuration = new DateTime(0,0,0,0,0,1);
        }
        public void onKeyDown(object sender, KeyEventArgs e)
        {
            if(e.Key == Key.Escape)
            {
                Application.Current.Shutdown();
            }
        }
    }
}

[ Voor 27% gewijzigd door dtech op 08-04-2008 16:39 ]


  • dtech
  • Registratie: Juni 2005
  • Laatst online: 19-09 15:37
Vreemd genoeg werkt dit weer wel.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using System;
-- snip --

namespace NewDramaClock
{

    public partial class Window1 : Window
    {
        public double Speed = 1;
        public DateTime SecondDuration;
        
        public Window1()
        {
            InitializeComponent();
            this.SecondDuration = new DateTime(1000);
        }
        public void onKeyDown(object sender, KeyEventArgs e)
        {
            if(e.Key == Key.Escape)
            {
                Application.Current.Shutdown();
            }
        }
    }
}

  • TeeDee
  • Registratie: Februari 2001
  • Laatst online: 19:52

TeeDee

CQB 241

Ik kan hier even geen Xaml verwerken, maar als ik een
C#:
1
DateTime melp = new DateTime(0, 0, 0, 0, 0, 1);
plaats, compileert dit wel, alleen geeft het @runtime een error.

Nu staat dat natuurlijk niet in verhouding met de Exception die jij krijgt, alleen is het wel 'vreemd' dat een
C#:
1
new DateTime(1000)
geen error geeft.

Heart..pumps blood.Has nothing to do with emotion! Bored


  • dtech
  • Registratie: Juni 2005
  • Laatst online: 19-09 15:37
Ja, complimeren doet hij bij nader inzien ook, het is een runtime error denk ik (dit staat namelijk bij uitvoer)
code:
1
2
3
Bouwen is gestart.
Bezig met compileren NewDramaClock
Bouwen met succes voltooid.


Ik heb nu echter iets anders. Ik ben bijna klaar (het veranderen van die DateTime was de "oplossing")
Maar nu heb ik een Timer ingesteld, maar hij lijkt niet te "tikken" (als ik de methode handmatig aanroep doet ie wat ie moet doen)
Hij lijkt wel te lopen, want de applicatie lijkt een miliseconde te stoppen op het moment dat de timer moet tikken
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public partial class Window1 : Window
    {
        public int StartInt = 1000;
        public System.Timers.Timer Tmr = new Timer();
    
        public Window1()
        {
            InitializeComponent();
            
            this.Tmr.Interval = this.StartInt;
            this.Tmr.Elapsed += new ElapsedEventHandler(TmrTick);
            this.Tmr.Enabled = true;
        }

        public void TmrTick(object source, ElapsedEventArgs e)
        {}

        public void ClockSpeedAdjust()
        {}
    }

  • TeeDee
  • Registratie: Februari 2001
  • Laatst online: 19:52

TeeDee

CQB 241

Heeft sharpdevelop geen debugging/trace whatever mogelijkheden? Jou stap voor stap je applicatie laten bouwen is nu niet echt de bedoeling van /14.

TmrTick wordt nu wel aangeroepen, alleen gebeurt er op deze manier niet veel natuurlijk.

Heart..pumps blood.Has nothing to do with emotion! Bored


  • dtech
  • Registratie: Juni 2005
  • Laatst online: 19-09 15:37
Debugmogelijkheden zaten een beetje verstopt (voor mij dan). TmrTick werd wel aangeroepen, maar er zat een fout in de code waardoor de veranderingen niet werden doorgevoerd.
Ik snap dat het niet de bedoeling is mijn programma stapje voor stapje te bouwen, en gelukkig lukt ook veel, maar als ik ergens niet via de reference lukt dan rest mij weinig anders :$
Ik heb nu nog een (laatste?) probleem. Ik probeer een Page Shape dat ik wil draaien. Ik dacht dit via rotatetransform te kunnen doen, maar er gebeurd niks, hoewel hij wel uitgevoerd lijkt te worden :( (althans, als ik er een breakpoint op zet dan komt staat hij daar stil)
Ik doe het zoals msdn zegt.
code:
1
2
3
4
5
6
7
8
9
<Path x:Name="HourHand" Data="M 0 15 L 10 0, 0 -60, -10 0 Z" 
                  Fill="{DynamicResource 
                            {x:Static SystemColors.ControlDarkBrushKey}}">
                <Path.RenderTransform>
                    <RotateTransform x:Name="xformHour"
                        Angle="{Binding Source={StaticResource angleHour}, 
                                        Path=Value.OffsetX}" />
                </Path.RenderTransform>
            </Path>

code:
1
2
3
4
// In een method van Window1
// HourAngle is een vooraf berekende double
RotateTransform RT3 = new RotateTransform(this.HourAngle,0,0);
this.HourHand.RenderTransform = RT3;
Pagina: 1