Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: Dynamicky přidání comboboxu ve WPF

Aktivity
Avatar
Milan
Člen
Avatar
Milan:1.7.2018 10:51

Ahoj, mám problém s dynamickým přidání comboxu ve WPF skrze button. Respektive jsem schopen přidat combobox, ale nejsem schopen přijít na to, jak ovlivnit jeho umístění v okně.

Zkusil jsem: Udělal jsem to následnovně.

v XAML:

<Canvas Name="LayoutRoot">
            <ComboBox Name="ComboBox1" Width="270" Height="30" Canvas.Left="308" Canvas.Top="198" >
                <ComboBoxItem Name="cbi1">Force</ComboBoxItem>
                <ComboBoxItem Name="cbi2">Line Force</ComboBoxItem>
            </ComboBox>
        </Canvas>

Kód:

private void ButtonAddLoad_Click(object sender, RoutedEventArgs e)
        {
            //AddLoad addLoad = new AddLoad();
            //addLoad.GetLoad();

            ComboBox addLoad = new ComboBox();
            addLoad.Width = 250;
            addLoad.Height = 30;
            ComboBoxItem addLoad_Item1 = new ComboBoxItem();
            addLoad_Item1.Content = "Force";
            addLoad.Items.Add(addLoad_Item1);
            ComboBoxItem addLoad_Item2 = new ComboBoxItem();
            addLoad_Item2.Content = "Line Force";
            addLoad.Items.Add(addLoad_Item2);
            LayoutRoot.Children.Add(addLoad);
        }

Tímto se mi vytvoří jeden combox nahoře v levo okně, ale nevím jestli se jich vytvoří 10 když 10x kliknu, protože se mi překrývají a nedaří se mi je odsazovat.

A ještě jeden dotaz. Vytvořil jsem si třídu, kde jsem chtěl mít ten kód, a jen v buttonu vyvolanou instanci a metodu, ale to mi nefunguje, nevíte proč?

class AddLoad : Steel
    {
        public void GetLoad()
        {
            ComboBox addLoad = new ComboBox();
            addLoad.Width = 250;
            addLoad.Height = 30;
            ComboBoxItem addLoad_Item1 = new ComboBoxItem();
            addLoad_Item1.Content = "Force";
            addLoad.Items.Add(addLoad_Item1);
            ComboBoxItem addLoad_Item2 = new ComboBoxItem();
            addLoad_Item2.Content = "Line Force";
            addLoad.Items.Add(addLoad_Item2);

            LayoutRoot.Children.Add(addLoad);
        }
    }

Díky moc za radu.

Editováno 1.7.2018 10:52
 
Odpovědět
1.7.2018 10:51
Avatar
Neaktivní uživatel:1.7.2018 11:30
addLoad.SetValue(Canvas.LeftProperty, /*třeba*/10);
//nebo
Canvas.SetLeft(addLoad, 10);

A nefunguje ti to protože

  1. okno má svou vlastní třídu
  2. všechny prvky jsou privátní

A proč používáš <code>Canvas</co­de>?

Editováno 1.7.2018 11:33
Nahoru Odpovědět
1.7.2018 11:30
Neaktivní uživatelský účet
Avatar
Milan
Člen
Avatar
Milan:1.7.2018 12:06

Ahoj,

proč Canvas to nevím, už jsem nevěděl co, tak jsem prostě googlil. Jestli je nějaký lepší způsob, tak prosím jaký?

A prosím tě, neporadil by jsi jak s tou třídou? V té mé jsem zkoušel dědit přímo z Window a k LayoutRoot jsem šel skrze Instanci Steel. Ale stejně mi to nefunguje. A předpokládám, že když mi to přídní bxu funguje ve třídě steel, která dědí z Windo, tak nechápu proč mi to nejde z jiné třídy.

 
Nahoru Odpovědět
1.7.2018 12:06
Avatar
Odpovídá na Milan
Neaktivní uživatel:1.7.2018 12:15

Jednodušší by měl být <code>Grid</code>. Sice se musíš pohrát s věcmi jako <code>WrapPanel</co­de>, ale není to žádný problém.

comboBoxesWrapPanel.Children.Add(addLoad);

apod.

Třídu bych prostě neřešil, já to vždycky nechávám ve <code>Window</code>

Nahoru Odpovědět
1.7.2018 12:15
Neaktivní uživatelský účet
Avatar
Milan
Člen
Avatar
Milan:1.7.2018 13:17

No já nevím jestli to nějak vyřeší můj problém. Protože prostě nevím, jak přidávat souřadnice těm boxům. Šlo použít .Location, ale to ne WPF mi nejde. Jednoduše si představuju, že budu mít nějakou pozici a pak udělám něco jako i+=30. atd... Ale to asi nejde.

 
Nahoru Odpovědět
1.7.2018 13:17
Avatar
Odpovídá na Neaktivní uživatel
Neaktivní uživatel:1.7.2018 14:34

Ještě obrázek.

Editováno 1.7.2018 14:36
Nahoru Odpovědět
1.7.2018 14:34
Neaktivní uživatelský účet
Avatar
Odpovídá na Neaktivní uživatel
Neaktivní uživatel:1.7.2018 14:40

Jestli to chceš těsně vedle sebe (nebo s mezerou – na to použij <code>Margin</co­de>), prostě to hoď do WrapPanelu kódem výš. Jinak přes Row a Column.

Achjo, já se z toho ITN zblázním. První zapomenu přihodit obrázek, potom už to nejde a když teda na to chci odpovědět, radši se to edituje.

Nahoru Odpovědět
1.7.2018 14:40
Neaktivní uživatelský účet
Avatar
Milan
Člen
Avatar
Odpovídá na Neaktivní uživatel
Milan:1.7.2018 16:09

Nakonec jsem to nechal přes ten Canvas

Canvas.SetTop(addLoad, x);
x+=40;

A přes button tam naklikám i 100 comboboxů. Ale teď zase nevím jak získat jednotlivé indexy :-). nevím jak přijít, jak se ty comboboxy jmenují. K tomu jendomu comboxu jsem vytvořil:

private void ComboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            int index = ComboBox1.SelectedIndex;
            TextBoxSelec.Text = index.ToString();
        }

Ale reaguje to jen čistě na ten jeden combobox, který mám uvedený v Canvas. Na ty další ne. Nevíš prosím, jak toto vyřešit?
Ve finále budu ke každému combboxu tvořit i textbox, které budou na sobě závislé, ale tedy nerozumím tomu, jak se k nim dostat.

Editováno 1.7.2018 16:10
 
Nahoru Odpovědět
1.7.2018 16:09
Avatar
Neaktivní uživatel:1.7.2018 17:19

XAML si udělej sám. A bez ComboBoxu a s WrapPanelem(teda doporučuju).

private void ButtonAddLoad_Click(object sender, RoutedEventArgs e)
        {
            ComboBox addLoad = new ComboBox();
            addLoad.Width = 250;
            addLoad.Height = 30;
            ComboBoxItem addLoad_Item1 = new ComboBoxItem();
            addLoad_Item1.Content = "Force";
            addLoad.Items.Add(addLoad_Item1);
            ComboBoxItem addLoad_Item2 = new ComboBoxItem();
            addLoad_Item2.Content = "Line Force";
            addLoad.Items.Add(addLoad_Item2);
            //odted jsou zmeny
            addLoad.Margin = new Thickness(5, 0, 5, 0);
            addLoad.SelectionChanged += ComboBox_SelectionChanged();
            addLoad.SelectionChanged += ComboBox_SelectionChanged;
            TextBox tb = new TextBox();
            CBsWP.Children.Add(addLoad);
            TBsWP.Children.Add(tb);
        }
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
             int index = (sender as ComboBox).SelectedIndex;
             int tbIndex = WP.Children.IndexOf(sender);
             (TBWP.Children[tbIndex] as TextBox).Text = index.ToString();
        }

Ještě se s tím trochu pohraj, tohle bylo jen aby ti to vůbec nějak fungovalo. Tak např. nechápu, proč mi to vždycky napsalo "1" :-) Ještě zkusím pořešit.

Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
Nahoru Odpovědět
1.7.2018 17:19
Neaktivní uživatelský účet
Avatar
Odpovídá na Neaktivní uživatel
Neaktivní uživatel:1.7.2018 17:25

Aha, tak bys to měl mít v pořádku. Zkoušel jsem to na trochu jiném kódu. :-)

Nahoru Odpovědět
1.7.2018 17:25
Neaktivní uživatelský účet
Avatar
Odpovídá na Neaktivní uživatel
Neaktivní uživatel:1.7.2018 17:28

A klidně to můžeš umístit jen do jednoho WP. To pak vyřešíš tak, že Btn je mimo a TB a CB rozeznáš podle <code>index % 2</code>

Nahoru Odpovědět
1.7.2018 17:28
Neaktivní uživatelský účet
Avatar
Milan
Člen
Avatar
Milan:1.7.2018 18:00

Díky moc. Pokusil jsem se zprovoznit to co jsi psal výše.

  1. nejde mi

addLoad.Selec­tionChanged += ComboBox_Selec­tionChanged();
Proč to máš 2x pod sebou, bez argumentu mi to nefunguje (Není dán žádný argument ......)
2)
int tbindex = TBsWP.Children­.IndexOf(sender);
Tady mi to píše, že nemůžu převést object na System.Window­s.UIElement

tomu teda moc nerozumím :-/

Editováno 1.7.2018 18:01
 
Nahoru Odpovědět
1.7.2018 18:00
Avatar
Odpovídá na Milan
Neaktivní uživatel:1.7.2018 18:20
  1. Sorry, má tam být jen to bez závorek.
  2. Zase nedávám pozor při kopírování kódu – <code>sender as TextBox</code> – a kdes to vzal? Nebo jsi něco už konečně zkusil sám? :-)
Nahoru Odpovědět
1.7.2018 18:20
Neaktivní uživatelský účet
Avatar
Milan
Člen
Avatar
Odpovídá na Neaktivní uživatel
Milan:1.7.2018 18:30

No já tu pořád něco zkouším sám, ale mocmi to nefunguje :-). Obojí jsem si myslel, ale když tam mám sender as Textbox, tak na poslední řádku mi to píše, že jsem mimo rozsah platných hodnot.

Zkusil jsem
TextBoxSelec.Text = index.ToString();

a reaguje to na každý nový combobox, takže jen vyřešit to plnění nového texboxu. :)

Editováno 1.7.2018 18:31
 
Nahoru Odpovědět
1.7.2018 18:30
Avatar
Odpovídá na Milan
Neaktivní uživatel:1.7.2018 18:37

Druhá metoda mého kódu, ale na konec druhého řádku dej místo <code>sender</code> <code>sender as ComboBox</code>

Nahoru Odpovědět
1.7.2018 18:37
Neaktivní uživatelský účet
Avatar
Milan
Člen
Avatar
Odpovídá na Neaktivní uživatel
Milan:1.7.2018 18:41

Ano, místo as TexBox, tam chtělo dát ComboBox a ještě to chtělo brát Index z CBsWP, ty jsi tady měl jen WP a já tam zkoušel jen TBsWP. Děkuji moc, už to funguje.

 
Nahoru Odpovědět
1.7.2018 18:41
Avatar
Milan
Člen
Avatar
Milan:1.7.2018 19:15

Takže funkční kod, díky moc Andy Scheuchzer:

private void ButtonAddLoad_Click(object sender, RoutedEventArgs e)
        {
            ComboBox addLoad = new ComboBox();
            addLoad.Width = 250;
            addLoad.Height = 30;
            ComboBoxItem addLoad_Item1 = new ComboBoxItem();
            addLoad_Item1.Content = "Force";
            addLoad.Items.Add(addLoad_Item1);
            ComboBoxItem addLoad_Item2 = new ComboBoxItem();
            addLoad_Item2.Content = "Line Force";
            addLoad.Items.Add(addLoad_Item2);
            addLoad.Margin = new Thickness(5, 0, 5, 0);
            addLoad.SelectionChanged += ComboBox_SelectionChanged;
            TextBox tb = new TextBox();
            tb.Width = 100;
            tb.Height = 30;
            CBsWP.Children.Add(addLoad);
            TBsWP.Children.Add(tb);
        }

        private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            int index = (sender as ComboBox).SelectedIndex;
            int tbindex = CBsWP.Children.IndexOf(sender as ComboBox);
            (TBsWP.Children[tbindex] as TextBox).Text = index.ToString();
        }
 
Nahoru Odpovědět
1.7.2018 19:15
Avatar
Neaktivní uživatel:6.7.2018 18:15

Sorry, že tak pozdě, ale snad to nevadí. Pokud opravdu chceš dělat tyhle věci z jiné třídy, předej v parametrech <code>StackPa­nel</code>, <code>ComboBox</co­de> nebo <code>TextBox</co­de>.

Nahoru Odpovědět
6.7.2018 18:15
Neaktivní uživatelský účet
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 18 zpráv z 18.