Witam jak odwołać się do elementu który wstawiłem do pewnego wiersza do Gridu mam już dostęp do okna mam dostęp do tabeli głównej, nie wiem jak znaleźć element w tabeli i odwołać się do niego. Jest to kontrolka którą tam wstawiłem. Chodzi mi o dostęp poprzez Grid.
Strzelam, że możesz dla tej kontrolki, którą tam wstawiłeś ustawić właściwość x:Name="control"
i po tej nazwie odwołać się do kontrolki w pliku z rozszerzeniem *.xaml.cs
Najlepiej jak pokażesz kod i napiszesz co chcesz osiągnąć po pobraniu elementu.
Nie powinieneś odnosić się do pliku *.xaml
z poziomu *.xaml.cs
w taki sposób mimo to, że będzie to działać.
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TextBox x:Name="hMyTextBox" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</Window>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
hMyTextBox.Text = "ustawiam tekst w textBox odwołując się po x:Name";
}
}
- Kluczowe znaczenie ma tu oddzielenie "widoku" od "logiki". Należy stworzyć sobie klasę, która będzie pośredniczyć między widokiem a Twoją logiką.
Jest to tzwViewModel
. Stwórz sobie taką klasę:
public class MainWindowViewModel
{
}
- Jeżeli masz kontrolkę
TextBox
na 99% jedyne, czego będziesz potrzebował to ustawiać i pobierać tekst. Stwórzmy więc właściwość wViewModelu
public class MainWindowViewModel
{
private string myText;
public string MyText
{
get
{
return myText;
}
set
{
myText = value;
}
}
}
- Teraz musimy powiązać za pomocą
Binding
tekst z naszej kontrolki z właściwością w naszej klasie.
Pierwsze co musimy zrobić to utworzyć instancję klasy w widoku:
<Grid>
<Grid.DataContext>
<local:MainWindowViewModel x:Name="ViewModel"/>
</Grid.DataContext>
<TextBox VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
Następnie wiążemy DependencyProperty
z kontrolki do właściwości
w klasie:
<TextBox
VerticalAlignment="Center"
HorizontalAlignment="Center"
Text="{Binding Path=MyText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
Należy wytłumaczyć tutaj 3 rzeczy:
a) Binding Path=MyText
- Określa, z którą właściwością wiążemy określone DependencyProperty
b) Mode=TwoWay
- Określa, że wiązanie odbywa się w obie strony, czyli wartość w ViewModelu
zmieni się kiedy wpiszesz coś w kontrolkę, ale tekst w kontrolce zmieni się także wtedy, kiedy ręcznie zmienimy wartość w ViewModelu
c) UpdateSourceTrigger=PropertyChanged
- Określa warunek, kiedy ma być pobrana wartość z ViewModelu
i zapisana w TextBox.Text
, w naszym przypadku będzie to użycie interfejsu INotifyPropertyChanged
Od tej pory za każdym razem, gdy zmieni się tekst w kontrolce zostanie on zapisany do Twojego ViewModelu
. Odczytać go możesz w posty sposób:
MessageBox.Show("Tekst w kontrolce: " + ViewModel.MyText);
- Problem powstaje, gdy będziesz potrzebował z poziomu kodu zmienić wartość w ViewModel np.:
ViewModel.MyText = "Nowy tekst";
Zauważysz wtedy, że tekst w kontrolce się nie zmienił. Dlaczego? Dlatego, że kontrolka nie wie, że wartość w ViewModelu
się zmieniła i cały czas nasłuchuje zdarzenia z interfejsu INotifyPropertyChanged
. Zaimplementujmy go więc i powiadomimy kontrolkę, że jak zmienimy wartość w ViewModelu
, kontrolka ma odświeżyć tekst:
public class MainWindowViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private string myText;
public string MyText
{
get
{
return myText;
}
set
{
myText = value;
NotifyPropertyChanged("MyText");
}
}
}
Kluczem jest ten zapis:
NotifyPropertyChanged("MyText");
Za każdym razem, kiedy zmienimy wartość w ViewModel.MyText
powiadamiamy wszystkie kontrolki które są powiązane z tą właściwością, że mają się odświeżyć.
I to na tyle :)
Takie rozwiązanie zapewnia Ci bezpieczeństwo przed nieprawidłowym użyciem kontrolki, ponieważ jedyne do czego masz dostęp to odczyt i zapis tekstu z kontrolki. Nie masz dostępu do żadnych innych informacji o niej, ponieważ cały design i style będą w widoku.