Two-way binding

1

Witam!

Mam takie szybkie pytanie. Jak zrealizować binding w obydwie strony? - tzn. zmieniam wartość jakiegoś pola w mojej klasie i automagicznie zmienia mi się zawartość np. textboxa (to jeszcze umiem, używając INotifyPropertyChanged ) ale też, jeżeli zmienię zawartość texboxa chciałbym, żeby wartość mojego pola również uległa zmianie, a to się nie dzieje. Nie satysfakcjonuje mnie event OnTextChanged, czy coś podobnego, bo musi być coś bardziej "profesjonalnego" (mam rację? :O).

Pozdrawiam, Wronq!

0

Hmm... Nie wiem, czy dokładnie przeczytałeś o tym co napisałem. W każdym razie nie znalazłem odpowiedzi na moje pytanie. Podałeś mi najprostszy przykład bindowania. W sumie się zastanawiam, czy takie bindowanie różni się czymś od zwykłego "textBox1.Text = student.Name;" ?
Ja natomiast chcę osiągnąć automatyzację w pewnym stopniu. Czyli np. gdzieś w programie dam sobie student.Name = "Stefan"; i automatycznie w textboxie pojawia mi się Stefan - to nauczyłem się realizować. Nurtuje mnie problem w drugą stronę - wpisuję w textboxie Czesław i automatycznie student.Name == "Czesław". Jaśniej troszkę? (chociaż sądzę, że poprzednie też było ok)

Pozdrawiam, Wronq!

0

Ja widzę tu tylko możliwość wykorzystania OnTextChange. Referencję do obiektu możesz wpisać w Tag danego textboxa. Zalecam jednak ostrożność, bo zmiana w textbox spowoduje uaktualnienie w obiekcie, co spowoduje uaktualnienie w textbox i tak w kółko. Możesz na przykład sprawdzać czy poprzednia wartość różni się od ustawianej.

0

Coś robisz źle. Ja binduje sobie textBoxa do zmiennej i wszystko działa w obie strony. Mode=TwoWay i zaimplementowane property changed i ustawione w bindowaniu że gdy property sie zmieni.

0

Twoja zmienna musi być publiczną właściwością.

0

@On: Mógłbyś pokazać kawałek kodu? Może faktycznie popełniam jakiś głupi błąd gdzieś...
@Krzyś: To jest oczywiste, inaczej ciężko byłoby zaimplementować OnPropertyChanged

Napisałem coś takiego:

 

textBox1.DataBindings.Add(new Binding("Text", this, "Text", false, DataSourceUpdateMode.OnValidation));
this.DataBindings.Add(new Binding("Text", textBox1, "Text", false, DataSourceUpdateMode.OnValidation));

private void button1_Click(object sender, EventArgs e)
{
    this.Text = "Blah";
}

private void button2_Click(object sender, EventArgs e)
{
    this.textBox1.Text = "Blah2";
}

To faktycznie działa i nie jest najgorzej... Tylko powstaje nowe pytanie - jak mogę zbindować coś do swojej klasy (np. student.DataBindings = ...) i czy wtedy również to zadziała?

0

MainWindow.xaml

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Name="myWindow" Height="350" Width="525">
    <Grid>
        <TextBox Height="40" Width="200" Text="{Binding ElementName=myWindow, Path=MyProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" TextChanged="TextBox_TextChanged" >
            
        </TextBox>
        <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="166,218,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
    </Grid>
</Window>

MainWindow.xaml.cs

using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        private string myProperty;
        public string MyProperty
        {
            get { return this.myProperty; }
            set
            {
                this.myProperty = value;
                OnPropertyChanged("MyProperty");
            }
        }
        public MainWindow()
        {
            InitializeComponent();
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string name)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(name));
        }

        private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            MessageBox.Show(MyProperty);
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            MyProperty = "asd";
        }
    }
}
0

Czy istnieje możliwość użycia XAMLa bez WPF? Ja pracuję pod WinFormsami i... no nie wiem czy się da tak zrobić.

0

XAML bez WPF raczej nie, choć nie wiem, nie znam się. Nie zauważyłem że robisz WinForms, sory. Chyba pozostaje czekać na specialiste od Formsów, lub przerzucić się na WPF bo Formsy odchodzą do lamusa ;).

0

WPF in WinForm: http://www.switchonthecode.com/tutorials/wpf-tutorial-using-wpf-in-winforms
Z tego korzystałem i dosyć dobrze działa.
Aczkolwiek jeśli jeszcze tylko możesz, rzuć WinFormy i przejsc na WPF.

0

Nie, no proszę was. Jedynym sposobem na "automatyczne" bindowanie jest XAML w WinFormsach? Nie wierzę.

Nie przepadam za WPF jest dla mnie dosyć uciążliwe i mam niemiłe doświadczenia. Pamiętam, że kiedyś chciałem wykonać jakąś operację jeszcze przed inicjalizacją formy, gdzie w WinFormsach zrobiłbym to w klasie Program w Main, a tam czegoś takiego nie znalazłem. Poza tym niektóre mechanizmy są dla mnie niezrozumiałe i manipulacja grafiką za pomocą XAMLa jest taka sobie jak dla mnie - to samo mogę zrobić normalnie w kodzie, może wymagać to będzie troszkę więcej pracy, ale za to będzie dla mnie przejrzyste i logiczne.

0

Takie rzeczy piszesz, że aż muszę Ci odpowiedzieć:

1.) Co rozumiesz przez bindowanie XAML w WinForm? Tam są całkiem inne kontrolki, oparte na innych bibliotekach, nie podepniesz tak łatwo bindingu WPF'owskiego do kontrolki WinFormowej. Dlatego jakbyś w aplikacji WinFormowej chciał mieć możliwości kontrolek WPF'a to tylko przez ElementHost.

2.) Przed inicjalizacją:
2.1.) - w App.xaml

    public partial class App : Application
    {

        public App() : base()
        {
            // co ci się podoba
        }
    }
 

2.2.) http://msdn.microsoft.com/en-us/library/system.windows.application.startup.aspx
Jedno z tych 2 rozwiązań pewnie robi to co chcesz, za późno jest, abym ci powiedział które.

3.) Ciekawe ile by Ci zeszło zrobienie w WinFormach okna programu które jest rozciągalne, a 3 z paneli ( gridów ) rozciąga się w inny sposób - jeden 6 razy szybciej, a drugi 2 od pierwszego, a do tego panel boczny - menu które się nie skaluje. Jest to około 15 linii w xaml. I do tego wygląda super przejrzyście - opinie moje i 2 kolegów, kiedy pracowaliśmy przy studenckim projekcie.

btw poprawcie mnie jutro bo pewnie błędy porobiłem.

0
  1. No właśnie wydaje mi się, że to jest sprzeczne w pewien sposób. Poza tym zapytałem się tylko, czy to jest możliwe i w życiu bym się przy takim rozwiązaniu nie upierał, a wręcz go unikał.
    2, 3) O jeju. Ja się pytam o bindowanie w WinFormsach, a nie kontrolki czy inne rzeczy w WPFie. Sądzę, że jeżeli nie są mi potrzebne nie wiadomo jak wypasione kontrolki, to spokojnie obędę się bez WPFa, a nawet jeżeli byłaby mi potrzebna mega grafika to zaprzęgam do pracy jakąś bibliotekę graficzną i tyle mojego zdania na ten temat.

Zaciekawiłeś mnie stwierdzeniem "jeden rozciąga się szybciej od drugiego" to nie miałby rozciągać się "razem z myszką", tylko z określoną prędkością/przyspieszeniem w jej stronę? Ale to już offtop, więc wracam do tematu, bo nadal nie znalazłem odpowiedzi.

0

A "data binding c#" nic nie znajduje na googlach?

0

Znalazłem coś na ten temat na stronach msdnu (lecz chyba tylko WPF :( ), forum i jakiś fajny artykuł, który może mi pomóc. I tylko tyle z sensownych rzeczy.

0

No, jej. Drugi link był już podany i wg mnie nie ma nic wspólnego z tematem. Pierwszy link to chyba pierwszy wynik z google i dotyczy on w większości datagrida, a czy to ma się jakoś do mojego problemu - nie jestem pewien.

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