2013-06-08 8 views
20

Jestem NIESAMOWITĄ i bardzo walczę z tym, co wydaje się być bardzo prostym zadaniem. Jak zmodyfikować właściwość MainWindowTextBlock, z innego pliku CS. Dokładne rozwiązanie kodu byłoby niezwykle pomocne.Jak uzyskać dostęp do WPF MainWindow Controls z mojego własnego pliku .cs

Poniżej znajduje się okrojony kod. Czy korzystanie z klasy statycznej powoduje dodatkowe problemy?

w pliku: 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> 

w pliku: MainWindow.xaml.cs

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

w pliku: 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"; 
     } 
    } 
} 

Odpowiedz

0

musisz utworzyć wystąpienie MainWindow.

Ale nie powinno być powodu, aby to robić, ponieważ zostanie to zrobione automagicznie w aplikacji WPF. Chyba że masz konkretny powód, aby to zrobić (co wątpię w to pytanie i dlatego, że mówisz, że jesteś nowicjuszem).

15

Możesz to osiągnąć za pomocą MVVM. Nie należy bezpośrednio uzyskiwać dostępu do formantów w widoku, używając jego nazwy z innej klasy. Musisz użyć właściwości wiążących.

Przede wszystkim dodać klasę, to będzie Twój ViewModel Dodaj swoje właściwości do tej klasy, które będą zbindowanych do kontroli wejściowych w View.

Student ViewModel

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

app.config

Teraz trzeba dodać do tego widoku modelu jako zasób w swoim app.config pliku. Najpierw dodaj odwołanie do przestrzeni nazw do pliku app.config, na którym znajduje się maszyna wirtualna. [xmlns: local = "clr-namespace: WpfApplication2].. Dodaj swoją klasę VM jako zasób, określając swoją nazwę klasy Widok modelu (studencki)

<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

Ustaw DataContext z kluczem zasobów dodany do app.config i ustawić wiązania do właściwości określonej w Studenckim widoku modelu.

<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

Jak, dlaczego nie zostanie skompilowany, będę zakładać błąd kompilatora jesteś ge Wp jest ...

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

Dzieje się tak dlatego, że próbujesz uzyskać dostęp do TextBlock1 jakby to były statyczne. Jak stwierdził @JeffRSon, najpierw utwórz instancję klasy MainWindow.

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

Zakładam może chcesz wyświetlić okno, jak również ...

mainWindow.ShowDialog(); 
1

Zastosowanie MVVM pattern dostęp do właściwości sterowania i modyfikować je:

public class Student 
{ 
    public Student() 
    { 
    } 

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

Ustaw DataContext z XAML w kodzie za:

this.DataContext = new Student(); 

Bind właściwość Tekst Nazwa:

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

Ponieważ nikt inny nie ma właściwie odpowiedział na pytanie ja powiem ci, jak osiągnąć to, co chcesz, ale nie słuchać plakatów który powiedział, że w prawdziwa aplikacja, której można użyć MVVM. Jednak są takie chwile, kiedy trzeba zrobić co pytasz więc kod czego potrzebujesz to:

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

miła odpowiedź, ale ja po prostu chciałem powtórzyć pogrubioną czcionką: ** „ale nie słuchać plakatów który powiedział, że w rzeczywistej aplikacji należy użyć MVVM” ** – Sharky

+5

Wielką odpowiedź, ale w Jeśli ktoś naprawdę za tym tęsknił ... ** "ale słuchaj plakatów, które powiedziały, że w prawdziwej aplikacji używałbyś MVVM" **. –

+1

Nie otrzymuję generalizacji porady bonusowej w ogóle. Istnieje kilka powodów, dla których w ten sposób potrzebujemy kodu źródłowego. na przykład niestandardowe kodowanie style.xaml za pomocą kodu proceduralnego dla użycia funkcji obsługi w stylach dla metod, dla których xaml nie jest wystarczająco algorytmem. –

2

Zasadniczo istnieją więcej niż 2-3 metody. Podana metoda jest znacznie łatwiejsza do zrozumienia, niż uchwyt &. Możesz uzyskać dostęp do elementów sterujących MainWindow, postępując zgodnie z kodami (1), (2), (3), (4).

w pliku: 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(); 
    } 
    } 

w pliku: 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. 
     } 
    } 

Uwagi: -

  1. Jest to dobra praktyka, aby użyj kodu (2) po oknie LOADED nie w C ONSTRUCTOR.
  2. Kod (2) w konstruktorze może pozostawiać problemy z uruchomieniem.
  3. Inną prostą metodą jest użycie "ref MainWindow_field" przez przekazanie do Konstruktora każdej klasy LUB przypisanie '(MainWindow) Application.Current.MainWindow' do statycznego Main.
Powiązane problemy