Diskuze: WPF binding

C# .NET .NET (C# a Visual Basic) WPF binding American English version English version

Avatar
ostrozan
Redaktor
Avatar
ostrozan:

I když jsem prostudoval zdejší tutoriály - jaksi to asi pořád nechápu - pořád něco dělám špatně.

může mi prosím někdo na úplně triviálním příkladu poradit jak postupovat?

v hlavním okně mám jen základní grid a v něm tři textBlocky

<    x:Class="WpfBind.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="130" Width="105">
    <Grid>
        <TextBlock Height="23" HorizontalAlignment="Left" Margin="16,12,0,0" Name="textBlock1" Text="TextBlock" VerticalAlignment="Top" />
        <TextBlock Height="23" HorizontalAlignment="Left" Margin="16,35,0,0" Name="textBlock2" Text="TextBlock" VerticalAlignment="Top" />
        <TextBlock Height="23" HorizontalAlignment="Left" Margin="16,56,0,0" Name="textBlock3" Text="TextBlock" VerticalAlignment="Top" />
    </Grid>
</Window>
namespace WpfBind
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        Class1 c1 = new Class1();

        public MainWindow()
        {

            InitializeComponent();

        }
    }
}

a třídu která obsahuje jediné pole stringů

namespace WpfBind
{
    class Class1
    {

        string[] str = { "raz", "dva", "tri" };
        public Class1()
        {

        }
    }
}

a ptřeboval bych nabindovat to pole na TextBlocky v hlavním okně - tedy stringy z nich použít jako vlastnost text TextBlocků.

zkoušel jsem na této "kostře" všechno možné a vůbe se mi nedaří

 
Odpovědět 19.4.2014 9:51
Avatar
Odpovídá na ostrozan
Petr Domes (petrds):

v tomhle případě by sis musel ty textblocky generovat dynamicky podle počtu prvků v poli.

Pokuď by jsi měl vždy 3 textblocky, v té tvojí třídě si uděláš 3 property. Vytvoříš objekt a ten nastavíš do gridu (který si pojmenuješ)

gridVeKteremJsouTextBlocky.DataContext=objektMojiTridy;

textblocky budou vypadat následovně:

<TextBlock  Text="{Binding property1}" />
<TextBlock  Text="{Binding property2}" />
<TextBlock  Text="{Binding property3}" />

Podívej se na můj tutoriál
http://www.itnetwork.cz/…tyly-binding

Editováno 19.4.2014 10:52
 
Nahoru Odpovědět 19.4.2014 10:51
Avatar
Lako
Člen
Avatar
Odpovídá na ostrozan
Lako:

četl sis vůbec nějaký tutoriál?
Nemáš přiřazený datasource na class1
Nemáš to pole stringů jako property (což je při bindování "vhodné")
Nemáš vůbec nastavený binding v tom xamlu....
Rád bych ti pomohl, ale v tomhle případě by to znamenalo napsat to celé za tebe..

 
Nahoru Odpovědět 19.4.2014 21:33
Avatar
ostrozan
Redaktor
Avatar
ostrozan:

Petr Domes : dík - prostuduju

Lako: jistě že četl - a ty jsi četl můj dotaz?

uvádím tam pouze jakousi kostru programu do které jak jsem původně doufal někdo doplní tři , čtyři řádky kódu - ale asi to , jak jsem pochopil není tak triviální.

Ano - čekal jsem , že to napíše někdo celé -a prakticky jsi to i udělal -jen by mi pomohlo, kdyby to bylo přímo v tom kódu :)

 
Nahoru Odpovědět 20.4.2014 10:47
Avatar
Petr Domes (petrds):

Třída kterou se bude bindovat

public class MyClass
    {
        public string Text1 { get; set; }
        public string Text2 { get; set; }
        public string Text3 { get; set; }
    }

XAML

<Grid Name="bindingGrid" >
    <TextBlock Text="{Binding Text1}" Height="23" HorizontalAlignment="Left" Margin="16,12,0,0" Name="textBlock1"  VerticalAlignment="Top" />
    <TextBlock Text="{Binding Text2}" Height="23" HorizontalAlignment="Left" Margin="16,35,0,0" Name="textBlock2"  VerticalAlignment="Top" />
    <TextBlock Text="{Binding Text3}" Height="23" HorizontalAlignment="Left" Margin="16,56,0,0" Name="textBlock3"  VerticalAlignment="Top" />
</Grid>

Code behind

public MainWindow()
{
    InitializeComponent();
    MyClass mc = new MyClass();
    mc.Text1 = "Můj text1";
    mc.Text2 = "Můj text2";
    mc.Text3 = "Můj text3";
    bindingGrid.DataContext = mc;
}

Nyní by ti mělo být vše jasné :)

Editováno 20.4.2014 11:17
 
Nahoru Odpovědět 20.4.2014 11:15
Avatar
Petr Nymsa
Redaktor
Avatar
Odpovídá na Petr Domes (petrds)
Petr Nymsa:

Tady je problém, že při změně té property se kontrolky sami neobnoví. Lepší je využít INotifyProper­tyChanged nebo ještě lépe DependencyProperty

Nahoru Odpovědět 20.4.2014 11:17
Pokrok nezastavíš, neusni a jdi s ním vpřed
Avatar
Odpovídá na Petr Nymsa
Petr Domes (petrds):

záleží, co s tím chce dělat. Pokuď chce zobrazovat data, která se mění jen s celým objektem, tak stačí nový objekt nabindovat.

 
Nahoru Odpovědět 20.4.2014 11:22
Avatar
ostrozan
Redaktor
Avatar
Odpovídá na Petr Domes (petrds)
ostrozan:

naprosto jasné -dík

jinak to k čemu se chci časem dopracovat je kontinuální zobrazování dat přijatých přes com port - o příjem se stará příslušná třída, data můžou přijít kdykoliv a zatím to mám řešené ve WF tak, že pomocí časovače pravidelně z formuláře volám metodu co mi vrací hodnoty přijaté com portem, což není zrovna nejlepší řešení

 
Nahoru Odpovědět 20.4.2014 18:57
Avatar
Odpovídá na ostrozan
Petr Domes (petrds):

není zač, rád poradím :)

Jinak k tomu k čemu se chceš dostat poradím toto:

dataGridu nastav parametr

IsReadOnly="True"

pro kolekci objektů, které chceš zobrazit v dataGridu použij

ObservableCollection

nově přidané objekty se ihned zobrazí v dataGridu

Řešení serioveho portu.

Využij eventu serioveho portu: DataReceived
Ta se zavolá vždy když něco příjde na port. Příjmutá data si nějak zpracuješ a pak zavoláš nějakou vlastní eventu, kterou budeš mit registrovanou ve WPF, a tam už jenom přidáš do kolekce nový objekt s daty(automaticky se ti zobrazí).

Editováno 20.4.2014 20:07
 
Nahoru Odpovědět 20.4.2014 20:06
Avatar
ostrozan
Redaktor
Avatar
Odpovídá na Petr Domes (petrds)
ostrozan:

Tak zatím jsem tedy zkusil ten INotifyProper­tyChanged

tady je kód - pokud by zajímal nějakého začátečníka jako jsem já :)

tři TextBlocky + jeden button pro ověření funkčnosti - kliknutím se změní stringy v třídě i v kontrolkách

<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" Height="350" Width="263">
    <Grid Name="grid1"  Width="251" Height="314">
        <TextBlock Height="30" Margin="80,107,82,174" Name="textBlock1" Text="{Binding Str1}" VerticalAlignment="Center" Background="#FF80D87F" Width="80" HorizontalAlignment="Center" FontSize="22" />
        <TextBlock Height="30" Margin="80,159,80,122" Name="textBlock2" Text="{Binding Str2}" VerticalAlignment="Center" Width="80" Background="#FF80D87F" HorizontalAlignment="Center" FontSize="22" />
        <TextBlock Height="30" Margin="80,210,82,71" Name="textBlock3" Text="{Binding Str3}" VerticalAlignment="Center" Width="80" Background="#FF80D87F" HorizontalAlignment="Center" FontSize="22" />
        <Button Content="zmena" Height="23" Margin="85,66,81,222" Name="button1" VerticalAlignment="Center" Width="75" Click="button1_Click" HorizontalAlignment="Center" />
    </Grid>
</Window>
namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        Class1 c1 = new Class1();
        public MainWindow()
        {
            InitializeComponent();
            grid1.DataContext = c1;
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            c1.Str1 = "qwe";
            c1.Str2 = "asd";
            c1.Str3 = "zxc";
        }
    }
}
namespace WpfApplication1
{
    class Class1: INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(string info)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(info));
        }

        private string[] str={"raz","dva","tri"};

        public string Str1
        {
            get { return str[0]; }
            set { str[0] = value; NotifyPropertyChanged("Str1"); }
        }
        public string Str2
        {
            get { return str[1]; }
            set { str[1] = value; NotifyPropertyChanged("Str2"); }
        }
        public string Str3
        {
             get { return str[2]; }
             set { str[2] = value; NotifyPropertyChanged("Str3"); }
        }

        public Class1()
        {

        }
    }
}

Ale takhle to vypadá, že třída bude mít spoustu vlastností - spíš jsem počítal, že by stringy (texty pro TextBlocky) byly v nějaké kolekci - ale to jde asi jen při použití toho DataGridu?

jinak DataGrid asi nevyužiju- chtěl bych použít TextBlocky už jen pro to, že chci měnit třeba barvu pozadí, nebo barvu barvu/font písma v závislosti na hodnotách a nevím jestli je to vjednotlivých buňkách DataGridu možné.

 
Nahoru Odpovědět 20.4.2014 20:48
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 10.