2013-06-08 16 views
20

Sono un novizio e sono molto impegnato con quello che sembra dovrebbe essere un compito molto semplice. Come modifico una proprietà di MainWindowTextBlock da un altro file cs. Una soluzione di codice esatto sarebbe estremamente utile.Come accedere ai controlli WPF MainWindow dal proprio file .cs

Di seguito è riportato il codice ridotto. Il mio uso della classe statica mi causa problemi extra?

In File: MainWindow.xaml

<Window x:Class="TestApp1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <TextBlock x:Name="TextBlock1" HorizontalAlignment="Left" Margin="107,71,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top"/> 
    </Grid> 
</Window> 

In File: MainWindow.xaml.cs

namespace TestApp1 
{ 
public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
      TextBlock1.Text = "Setting Text from MainWindow"; 
      MyProgram.myProgramStart(); 
     } 
    } 
} 

In File: CodeFile1.cs

namespace TestApp1 
{ 
    public static class MyProgram 
    { 
     public static void myProgramStart() 
     { 
      // ... blah blah blah 

      // I want to do something like follows, but won't compile 
      MainWindow.TextBlock1.Text = "Setting Text from My Program"; 
     } 
    } 
} 

risposta

0

è necessario creare un istanza di MainWindow.

Ma non ci dovrebbe essere un motivo per farlo perché sarà fatto automaticamente in un'app WPF. A meno che tu non abbia una ragione specifica per farlo (che dubito a causa di questa domanda e perché dici che sei un novizio).

15

È possibile ottenere ciò utilizzando MVVM. Non devi accedere direttamente ai controlli in Visualizza usando il suo nome da un'altra classe. Devi usare le proprietà vincolanti.

Prima di tutto aggiungere una classe, questa sarà la vostra ViewModel aggiungi le strutture a questa classe che sarà binded ai controlli di input nel vostro View.

Student ViewModel

public class Student 
{ 
    public string Name 
    { 
     get { return "Setting Text from My Program"; } 
    } 
} 

app.config

Ora è necessario aggiungere a questa Altri modello come una risorsa nel vostro app.config file di . Innanzitutto aggiungi il riferimento allo spazio dei nomi alla tua app.config in cui risiede la tua VM. [xmlns: locale = "CLR-namespace: WpfApplication2].. Aggiungere la classe VM come una risorsa, specificando il vostro Visualizza nome della classe del modello (studente)

<Application x:Class="WpfApplication2.App" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      StartupUri="MainWindow.xaml" 
      xmlns:local="clr-namespace:WpfApplication2"> 

    <Application.Resources> 
     <local:Student x:Key="Student" /> 
    </Application.Resources> 
</Application> 

MainWindow.xaml

Impostare la DataContext con la chiave di risorsa aggiunto App.config e impostare il legame con la proprietà definita nella Student vista del modello.

<Window x:Class="WpfApplication2.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     DataContext="{StaticResource Student}" 
     Title="MainWindow" Height="350" Width="525"> 

    <Grid> 
     <TextBlock Text="{Binding Name}" Height="23" HorizontalAlignment="Left" Margin="127,124,0,0" Name="textBlock1" VerticalAlignment="Top" Width="214" /> 
    </Grid> 
</Window> 
0

per quanto riguarda il motivo per cui non si compila, si assumerà l'errore del compilatore si è ge tting è ...

An object reference is required for the non-static field, method, or property 'TestApp1.MainWindow.TextBlock1'

Questo accade perché si sta tentando di accedere a un TextBlock1 come se fosse statico. Come dichiarato @JeffRSon, crea prima un'istanza della tua classe MainWindow.

// Create an instance of MainWindow 
var mainWindow = new MainWindow(); 
mainWindow.TextBlock1.Text = "Setting Text from My Program"; 

presumo si consiglia di visualizzare la finestra così ...

mainWindow.ShowDialog(); 
1

Usa MVVM pattern per accedere alle proprietà del controllo e modificarli:

public class Student 
{ 
    public Student() 
    { 
    } 

    public string Name 
    { 
     get { return "Setting Text from My Program"; } 
    } 
} 

Impostare la DataContext del codice XAML nel codice sottostante:

this.DataContext = new Student(); 

associare la proprietà Text a Nome:

<TextBlock Text="{Binding Name}"/> 
36

perché nessun altro ha effettivamente risposto alla domanda che sto per dirvi come ottenere quello che vuoi, ma ascoltare i manifesti che ha detto che in una vera applicazione che useresti MVVM. Tuttavia ci sono momenti in cui è necessario fare ciò che si chiede in modo che il codice di cui hai bisogno è:

((MainWindow)System.Windows.Application.Current.MainWindow).TextBlock1.Text = "Setting Text from My Program"; 
+10

bella risposta, ma volevo solo ripetere in grassetto: ** "ma ascoltare i manifesti Chi ha detto che in una vera e propria applicazione che si usa MVVM" ** – Sharky

+5

Grande risposta, ma in caso qualcuno lo ha davvero mancato ... ** "ma ascolta i poster che hanno detto che in un'applicazione reale useresti MVVM" **. –

+1

Non capisco la generalizzazione del consiglio bonus. Ci sono diversi motivi per cui necessitare di code-behind in questo modo. per esempio. un code-behind personalizzato di style.xaml usando codice procedurale per l'uso di gestori in stili per metodi per cui xaml non è abbastanza algoritmico. –

2

Fondamentalmente ci sono più di 2-3 metodi. Dato il metodo è abbastanza più facile da capire handle &. È possibile accedere ai controlli di MainWindow seguendo i codici (1), (2), (3), (4).

In File: MainWindow.xaml.cs

public partial class MainWindow 
    { 
    internal static MainWindow Main; //(1) Declare object as static 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     Main =this; //(2) Defined Main (IMP) 
     var AnyClassORWindow=new Class1(); //Initialize another Class 
     AnyClassORWindow.ShowValue(); 
    } 
    } 

In File: Class1.cs

internal class Class1 : MainWindow //(3) Inherited 
    { 
     internal void Display() 
     { 
      MessageBox.Show(Main.TextBox1.Text); //(4) Access MainWindow Controls by adding 'Main' before it. 
     } 
    } 

Note: -

  1. E 'buona norma utilizzare il codice (2) dopo la finestra CARICATA non in C ONSTRUCTOR.
  2. Codice (2) nel costruttore può lasciare problemi di runtime.
  3. Un altro metodo semplice consiste nell'utilizzare "ref MainWindow_field" passando a Constructor di ogni classe OPPURE assegnare "MainWindow Application.Current.MainWindow" a Main statico.
Problemi correlati