Autor Beitrag
Ritzeratze
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 101



BeitragVerfasst: So 28.06.15 11:15 
Moin,

ich bekomme immer den o.g Fehler beim Versuch einen Button zu instanzieren. Leider klappt das nicht so sauber wie ich mir das Wünsche.
Folgende Code aus dem XAMl Dokument

ausblenden XML-Daten
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
<Window x:Class="WPF_Memory.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Memory" Height="470" Width="465" ResizeMode="NoResize">
    <Grid>
        <UniformGrid x:Name="spielfeld" Width="448" Height="448" HorizontalAlignment="Left" VerticalAlignment="Top" Rows="7" Columns="7" Margin="2"/>
        <Canvas>
            <Button x:Name="SchummelButton" Canvas.Top="390" Canvas.Left="348" Width="100" Height="40" IsEnabled="False">Schummeln</Button>
        </Canvas>
    </Grid>
</Window>


Im Anwendungscode instanziere ich den Button

ausblenden C#-Quelltext
1:
2:
3:
 Button SchummelButton = new Button();
 ....
 ....


und in der Methode möchte ich den Button auf
ausblenden C#-Quelltext
1:
SchummelButton.IsEnabled = true					

setzen. Dabei bekomme ich aber die Fehlermeldung System.NullReferenceException. Habe ich etwas vergessen, oder funktioniert das nicht auf diesem Wege?

Gruss
Ritze
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: So 28.06.15 11:54 
Wieso instanzierst Du den Button nochmal? Wenn der im XAML steht wird der doch automatisch instanziert.

Außerdem liest sich das so, als würdest du den Button nicht im selben Kontext instanzieren, wie du ihn dann benutzt.

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
Ritzeratze Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 101



BeitragVerfasst: So 28.06.15 13:02 
Danke Christian,

für Deine Antowrt.

Zitat:
Außerdem liest sich das so, als würdest du den Button nicht im selben Kontext instanzieren, wie du ihn dann benutzt.


Könntest Du mir das vielleicht näher erläutern? Wenn ich den Button in XAMl Code definiere, kann ich diesen nicht in einer beliebigen Methode ansprechen.Ich muss diesen also vorher instanzieren, ansonsten bekomme ich immer die NUllException.

Wie soll ich da sonst vorgehen?


Gruss
Ritze
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: So 28.06.15 13:53 
Wenn du etwas in Xaml definierst und im dort einen Namen gibt (hier SchummelButton) bekommst du auch eine Variable diesen Namens für die Window Class und kannst ihn innerhalb der Window Class benutzen.
Wenn du auf dem Window nochmal einen Button mit Namen SchummelButton erzeugt sollte das nicht mal kompilieren da es schon einen gibt.
Ich kann nur vermuten das du scheinbar irgendwo einen Button (in irgend einer anderen Klasse aber nicht dem Window) zu definieren versuchst und glaubst er hätte irgendwas mit dem Button auf dem Window zu tun. Dem ist nicht so. Wenn du irgendwas an dem Button ändern willst dann veröffentliche eine Methode, Property etc. an deiner Window Klasse über die du den Button Zustand von einer anderen Klasse aus ändern kannst. So ein Button ist etwas internes des Window und nur die Window klasse sollte es kennen und manipulieren. Alle anderen wenden sich also an das Window und nicht an den Button.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: So 28.06.15 15:10 
Und per MVVM bräuchtest du noch nichteinmal den Namen des Buttons, da jeder Zugriff über das ViewModel geschieht, welche per Binding mit der View kommuniziert.

Eine kurze Einführung in MVVM in deutsch findest du unter Model-View-ViewModel: Die Serie.
Ritzeratze Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 101



BeitragVerfasst: Mo 29.06.15 11:29 
Hi,

es ist egal wie ich den Button anspreche, ich bekomme immer die o.g. Fehlermeldung.
Bin schon am verzweifeln. Es ist auch kein anderer Button vorhanden.

Gruss Ritze
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mo 29.06.15 12:30 
Dann wäre ein größerer Ausschnitt des Codes notwendig um dir zu helfen.

Umgekehrt, versuch doch mal dein Problem in einer kleinen Testanwendung nachzustellen. Das ist ein üblicher Weg um sich einem Problem zu nähern. Erstell ein simple WPF Anwendung, werf einen Button drauf und versuch in im Code anzusprechen. Das solte funktionieren und jetzt nimmst du immer mehr von dem Code hinzu den du auch in deiner eigentlichen Anwendung im Umfeld des Buttons benutzt hast und schaust wann es aufhört zu funktionieren. Dann solltest du genug Anhaltspunkte haben um das Problem zu erkennnen.
Ritzeratze Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 101



BeitragVerfasst: Mi 01.07.15 21:11 
Ok ich schicke den Code einmal mit.

Am Anfang des Spieles , beim Mensch Zug soll der Button aktiviert sein, wenn der Computer zieht soll er deaktiviert sein.
Ich habe zu Beginn des Mensch Zuges eines MessageBox eingesetzt.

Möchte nur wissen wie ich den Button.IsEnabled = true setze bze Button.IsEnabled= false setze.

Gruss Ritze

Neue Version kommt. Ich habe wieder ein bißchen mehr verstanden.


Zuletzt bearbeitet von Ritzeratze am Mi 01.07.15 23:27, insgesamt 1-mal bearbeitet
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mi 01.07.15 22:37 
Das XAML ist anders als in deinem ersten Beitrag. Du hast das Window SchummelButton genannt so kannst du jetzt im Code auf das Window zugreifen und dein Button hat keinen Namen. Wie bereits erwähnt ohne Namen keine Variable. Also nimm dem Window den Namen weg und gib dem Button einen Namen.
Ritzeratze Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 101



BeitragVerfasst: Mi 01.07.15 22:43 
Hallo Ralf,

OK, habe ich gemacht. Trotzdem kann ich den Button nicht ansprechen.

Gruss


Zuletzt bearbeitet von Ritzeratze am Mi 01.07.15 22:56, insgesamt 1-mal bearbeitet
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mi 01.07.15 22:55 
Zitat:
also x:Name:"SchummelButton".


Richtig. Scheinst du doch verstanden zu haben ;)

Wenn du im XAML keinen Namen hast für ein Control erstellt er dafür auch keine Variable (welchen Namen sollte er der Variablen auch geben irgendwie durchnummerierte Variablen würden dir wohl kaum helfen). Denn Button gibt es natürlich trotzdem. Er hängt nur halt in einer Baumstruktur an seiner jeweiligen Parent object der hat einen Verweis auf den Button aber ohne direkte benammste Variable.

Ein hilfreiches Metamodel wie das funktioniert wäre vielleicht das du dir vorstellst das das Window ein Array hält mit allen Controls die auf ihm drauf liegen und angezeigt werden. Für die einzelnen Controls brauchst du dann keine Variable sie existieren ja im Array. Und damit man im Code einfach mit einzelnen Controls arbeiten kann ohne in diesem Array herumfuhrwerkeln zu müssen kann man denn Controls auch noch eine direkte Variable geben eben indem man ihn einen Namen gibt. Wenn du es genauer Wissen willst als das da irgendwie ein Array ist schau dir die VisualTreeHelper Klasse an.


Edit:

Zitat:
OK, habe ich gemacht. Trotzdem kann ich den Button nicht ansprechen.

Habe ich auch in deinem Code und ich kann.

Dein Xaml so geändert

ausblenden XML-Daten
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
<Window x:Class="WPF_Memory.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Memory" Height="470" Width="465" ResizeMode="NoResize">
    <Grid>
        <UniformGrid x:Name="spielfeld" Width="448" Height="448" HorizontalAlignment="Left" VerticalAlignment="Top" Rows="7" Columns="7" Margin="2"/>
        <Canvas>
            <Button x:Name="SchummelButton" Canvas.Top="390" Canvas.Left="348" Width="100" Height="40" Click="SchummelButton_Click" >Schummeln</Button>
        </Canvas>
    </Grid>  
</Window>


und dann einen Click Handler an den Button gehängt der den Button Text ändert. Und siehe da der Button Text ändert sich ohne Exceptions oder sonstige Probleme.

ausblenden C#-Quelltext
1:
2:
3:
4:
private void SchummelButton_Click(object sender, RoutedEventArgs e)
{
    SchummelButton.Content = DateTime.Now.Second.ToString();
}
Ritzeratze Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 101



BeitragVerfasst: Mi 01.07.15 23:07 
Der Button soll aber nur aktiviert oder eben nicht aktiviert sein.
Das ist ganz banal. Soweit ich das verstanden habe kann ich das mit IsEnabled = true oder false codieren. Und warum funktioniert das nicht ?
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mi 01.07.15 23:19 
Ich vermute du sprichst von der SchummelButton Varaiblen in MemoryFeld?

Da hast dort einfach irgendeinen anderen Button erzeugt den du nirgendwo angezeigst der auch nix mit dem auf dem Window zu tun hat nur die Variable heißt zufällig gleich.
Wenn du auf irgendwas auf dem Window zugreifen willst brauchst du auch eine Referenz darauf. Das UniformGrid hast du ja bereits an die Klasse übergeben das reicht aber so nicht um an den Button zu kommen der liegt ja nicht auf diesem Grid sondern daneben.
Um das was du da hast zu retten könntest du anstatt das UniformGrid an MemoryFeld zu übergeben dein MainWindow an MemoryFeld übergeben.
Also eher so

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
public MemoryFeld(MainWindow window)
{
   window.spielfeld; //Zugriff auf Uniformgrid
   window.SchummelButton // Zugriff auf den Button 
}


Ich würde dir anraten das du dir die Hinweise auf MVVM zu herzen nimmst. Dein Stil sieht eher nach gegen WPF arbeiten aus als nach mit WPF arbeiten.