IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
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í.
Avatar
rawen
Člen
Avatar
rawen:14.7.2015 17:39

Zdravím, mám takový problém, zkusím to co nejjednodušeji vysvětlit. :) Chtěl bych si naBindovat data z textBoxu do nějaké vlastnosti, já bych ale potřeboval ona data ještě převést na jiná, přesněji přes Converter v XAML. S tímhle by zatím nebyl problém. Problém je v tom, že když si udělám třídu, která onen Converter provádí, tak bych chtěl ono převádění dělat za použití dat z kolekce. Problém je v tom, že nevím jak té třídě onu kolekci z daty dát. Kdybych to měl vysvětlit na příkladu, tak dejme tomu že bych do textboxu psal jen číslo, třeba 2 a ona třída na Converter by mě do oné Bindované vlastnosti poslala item na 2. místě v kolekci. Zajímaloby mě jestli se to takhle dá vubec nějak udělat. Jediné co mě napadá je, že bych měl onu kolekci statickou, ale nepřijde mě to jako nejlepší nápad. Na internetu jsem nic podobného nenašel, přitom mě to přijde jako něco, s čím se muselo setkat hodně lidí pokud to jde nějak řešit. (btw. přes event na kontrolce a převáděním tam bych to dělat nechtěl). Předem děkuji za každý nápad. :)

Odpovědět
14.7.2015 17:39
Co můžeš naprogramovat dnes, neodkládej na zítřek.
Avatar
rawen
Člen
Avatar
rawen:15.7.2015 9:58

Co mě tak ještě napadá je, si udělat Singleton, který by v sobě měl onu kolekci s daty, což není problém naprogramovat, ale nejsem si jistý jestli je to programátorsky šťastně řešeno.

Nahoru Odpovědět
15.7.2015 9:58
Co můžeš naprogramovat dnes, neodkládej na zítřek.
Avatar
Odpovídá na rawen
sadlomaslox25:16.7.2015 20:21

pres MultiValueCon­verter. Do prvni hodnoty das tu kolekci a vevnitr pretypujes na IList nebo IEnumerable a druha hodnota bude ten index.

Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
 
Nahoru Odpovědět
16.7.2015 20:21
Avatar
rawen
Člen
Avatar
rawen:16.7.2015 23:44

Děkuji za odpověd, tímto způsobem jsem to už začal řešit, ale zaseknul jsem se na jedné věci. Že když takto přes třídu co provádí MultiValueConverter si převedu hodnoty, tak nevím jak tento výsledek dál předat. Vypadá to přibližně takto:

<TextBox>
    <TextBox.Text>
        <MultiBinding Converter="{StaticResource textConverter}">
            <Binding Path="Kolekce1" ElementName="mainWindow" />
            <Binding Path="Kolekce2" ElementName="mainWindow" />
        </MultiBinding>
    </TextBox.Text>
</TextBox>

Přičemž já bych chtěl takto získaný výsledek po převodu Bindovat do DependencyProperty, něco ve smyslu

<TextBox Text="{Binding mojeDependencyProperty}">

což ale nejde, protože by se text nastavoval víckrát. Nenapadá tě co s tím? :)

Nahoru Odpovědět
16.7.2015 23:44
Co můžeš naprogramovat dnes, neodkládej na zítřek.
Avatar
Odpovídá na rawen
sadlomaslox25:17.7.2015 9:38

tak to vyres v ramci ViewModelu. udelej si ve ViewModelu 3 property. tu kolekci, index vybrane veci z te kolekce a pak referenci na tu vybranou vec z kolekce. podle potreby to zesynchronizuje jak potrebujes. jednoduzsi je nektere z tech vlastnosti dat jako read only.

 
Nahoru Odpovědět
17.7.2015 9:38
Avatar
rawen
Člen
Avatar
Odpovídá na sadlomaslox25
rawen:17.7.2015 16:32

Zajímavý nápad, a jak bych pak takto vytvořenou třídu zapsal v XAML, to bych jako Bindoval ten objekt reprezentující ony 3 vlastnosti a byl by to klasický ValueConverter ?

Nahoru Odpovědět
17.7.2015 16:32
Co můžeš naprogramovat dnes, neodkládej na zítřek.
Avatar
Odpovídá na rawen
sadlomaslox25:18.7.2015 15:42

prvni varianta stim conventorem vypada asi takto

<StackPanel Name="view1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
            <StackPanel.Resources>
                <wpfTest:MyConverter x:Key="con" />
            </StackPanel.Resources>
            <TextBlock Text="Mesta"/>
            <ComboBox Name="combo" ItemsSource="{Binding Data}" DisplayMemberPath="Key" SelectedValuePath="Value"  />
            <TextBlock Text="Cislo ulice"/>
            <Slider Minimum="1" Name="slider" Maximum="{Binding ElementName=combo, Path=SelectedValue.Count}" TickPlacement="TopLeft" SmallChange="1" IsSnapToTickEnabled="True"/>
            <TextBlock Text="Nazev ulice"/>
            <TextBlock TextAlignment="Center" >
                <TextBlock.Text>
                    <MultiBinding Converter="{StaticResource con}">
                        <Binding ElementName="combo" Path="SelectedValue"/>
                        <Binding ElementName="slider" Path="Value"/>
                    </MultiBinding>
                </TextBlock.Text>
            </TextBlock>
        </StackPanel>
public class MyConverter:IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        try
        {
            var data = values[0] as IList;
            var position = int.Parse(values[1].ToString());

            return data[position - 1];
        }
        catch
        {
            return "N/A";
        }
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

public class ViewModelV1
{
    public Dictionary<string, List<string>> Data { get; set; }

    public ViewModelV1()
    {
        Data = new Dictionary<string, List<string>>()
        {
            {"Praha", new List<string>() {"Nova", "Zelena", "Oranzova"}},
            {"Brno", new List<string>() {"Polni", "Horní"}},
            {"Ostrava", new List<string>() {"Stodolní",}},
        };
    }
}

druha varianta stim rozsirenym viewmodelem vypada asi takto

<StackPanel Grid.Column="1" Name="view2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
    <TextBlock Text="Mesta"/>
    <ComboBox ItemsSource="{Binding Data}" SelectedItem="{Binding SelectedCity}" DisplayMemberPath="Name" />
    <TextBlock Text="Cislo ulice"/>
    <Slider Minimum="1" Maximum="{Binding SelectedCity.Streets.Count}" Value="{Binding SelectedStreetIndex}" TickPlacement="TopLeft" SmallChange="1" IsSnapToTickEnabled="True"/>
    <TextBlock Text="Nazev ulice"/>
    <TextBlock TextAlignment="Center" Text="{Binding SelectedStreetName}"/>
</StackPanel>
public class ViewModelV2:INotifyPropertyChanged
{
    private City _selectedCity;
    private int _selectedStreetIndex;
    public List<City> Data { get; set; }

    public class City
    {
        public string Name { get; set; }
        public List<string> Streets { get; set; }
    }

    public ViewModelV2()
    {
        Data = new List<City>()
        {
            new City()
            {
                Name = "Praha",
                Streets = new List<string>()
                {"Nova", "Zelena", "Oranzova"}
            },
            new City()
            {
                Name = "Brno",
                Streets = new List<string>()
                {"Polni", "Horní"}
            },
            new City()
            {
                Name = "Ostrava",
                Streets = new List<string>()
                {"Stodolní"}
            },
        };
    }

    public City SelectedCity
    {
        get { return _selectedCity; }
        set
        {
            _selectedCity = value;
            SelectedStreetIndex = 1;
            OnPropertyChanged();
        }
    }

    public int SelectedStreetIndex
    {
        get { return _selectedStreetIndex; }
        set
        {
            _selectedStreetIndex = value;
            OnPropertyChanged();
            OnPropertyChanged("SelectedStreetName");
        }
    }

    public string SelectedStreetName
    {
        get
        {
            try
            {
                return SelectedCity.Streets[SelectedStreetIndex - 1];
            }
            catch
            {
                return "N/A";
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}
 
Nahoru Odpovědět
18.7.2015 15:42
Avatar
rawen
Člen
Avatar
Odpovídá na sadlomaslox25
rawen:18.7.2015 22:21

Tohle mě až tak moc nepomohlo. Nakonec jsem to vyřešil trochu jinak. Při ConvertBack přenastavuju vlastnost na daném objektu (ten je v rámci převáděcí třídy jako private) a vracím prázdné pole. Při Convert se podívám co má daný (private) objekt v dané vlastnosti a vracím vypočítaný text. :) Každopádně děkuju za pomoc, kdybys neodepsal, tak bych se na to asi vykašlal a nechal to jako klasický event při změně na textBoxu, tak jako dík, tě můžu aspon označit jako řešitele. :D

Editováno 18.7.2015 22:23
Nahoru Odpovědět
18.7.2015 22:21
Co můžeš naprogramovat dnes, neodkládej na zítřek.
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 8 zpráv z 8.