Pobieranie elementu z tabeli Grid w WPF

0

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.

1

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.

0

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";
        }
    }
  1. 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 tzw ViewModel. Stwórz sobie taką klasę:
public class MainWindowViewModel
{
       
}
  1. Jeżeli masz kontrolkę TextBox na 99% jedyne, czego będziesz potrzebował to ustawiać i pobierać tekst. Stwórzmy więc właściwość w ViewModelu
public class MainWindowViewModel
{
        private string myText;
        public string MyText
        {
            get
            {
                return myText;
            }
            set
            {
                myText = value;
            }
        }
}
  1. 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);

  1. 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.

1 użytkowników online, w tym zalogowanych: 0, gości: 1