• úvod
  • témata
  • události
  • tržiště
  • diskuze
  • nástěnka
  • přihlásit
    registrace
    ztracené heslo?
    TENCOKACISTROMYProgramovani v C#, F# a dalsich jazycich pro .NET, Mono a ostatni CLI implementace
    TOOMIX
    TOOMIX --- ---
    PEETIK: není nic v error okně?
    PEETIK
    PEETIK --- ---
    Dnes jsem si řekl, že se zkusím mrknout co to vlastně to programování je :D Mno, tak sem si řekl, že se mrknu na C# a už po naistalováni Visual Studia 2022, jsem narazil na první eskapádu. Založím nový projekt - Console a po spuštění by mělo být viditelné tlačítko play nebo alespoň spustit pomocí F5. Jenže Play je disablované a F5 tímpádem také nic nedělá. Nějaká zrada mezi klávesnicí a židlí nebo nějaký špatný release VS? Dík
    TOOMIX
    TOOMIX --- ---
    TOOMIX
    TOOMIX --- ---
    Existuje nějaká cesta (kromě vlastního pluginu cdo VS), jak přebarvit/udělat tlustší snaplines ve WindowsForms Designeru ve Visual Studiu 2022? Hledám už asi hodinu a nic nenacházím

    PLACHOW
    PLACHOW --- ---
    Routy v Blazoru mohou být afaik pouze konstanty. Nedají se dynamicky generovat při startu aplikace jako například ve webforms (typicky v global.asax přes RouteCollection.MapRoute). Hardkódování cest v direktivách @page je samozřejmě napytel jen u trochu větších projektů. Dá se to ale alespoň částečně obejít. Cestu lze komponentě určit místo direktivy @page atributem @attribute [Route(CESTA)]. Například definice komponenty BlackList.razor s URL "/admin/blacklist" se dá provést takto:


    Kdy je cesta definována centrálně:
    MORMEGIL
    MORMEGIL --- ---
    CERMI_FOX: Složka není něco, co by mělo nějaký obraz v C#. Viditelnost řízená podle namespacu (resp. package) je v Javě a vždycky mi to přišlo divné, protože do namespacu se můžeš kdykoli komukoli vecpat. Si to udělej internal, v jedné assembly si to snad uřídíš.
    TOOMIX
    TOOMIX --- ---
    NECROMAN: file partial by měla jít jen v jednom souboru, ale proč bych to pak dělal? 🤷
    NECROMAN
    NECROMAN --- ---
    TOOMIX: a jak bude fungovat file a partial classy dohromady, to tam nepíšou...
    CERMI_FOX
    CERMI_FOX --- ---
    TOOMIX: hezký, ale spíš bych ocenil možnost omezit scope třídy na složku / namespace. Tohle jen bude nutit cpát pomocné třídy/struktury do jednoho souboru.
    TOOMIX
    TOOMIX --- ---
    C# 11.0 přináší klíčové slovo file pro deklaraci tříd v rámci jednoho *.cs souboru

    file keyword - C# Reference | Microsoft Learn
    https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/file
    PEPSIN
    PEPSIN --- ---
    PLACHOW: když startuje blazor prochází stránky a hleda direktivy @page kvůli routungu

    A já bych rád manipulovat routingem na základě i jiných šat, například pozici v adresarove struktuře, ale třeba i vstupu z db.

    Ale možná fakt vymejslim kolo
    PLACHOW
    PLACHOW --- ---
    PEPSIN: tomu nerozumím. Jaká "registrace stránek"?
    PEPSIN
    PEPSIN --- ---
    Když uz se tu řešil ten blazor.

    Uvažoval jsem nad konceptem projít adresarove struktury na serveru a automatické registrace stránek. Má to smysl? Řeší to už někdo něco? Nevymyslim kolo?
    DATEL
    DATEL --- ---
    EMBI: díky, za odkaz se kouknu. K tomu ObservableCollection, ano právě že ClassFormData má pro každý combobox samostatnou property.
    EMBI
    EMBI --- ---
    DATEL: nainstaluj si Nuget https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/ . Vsechny tyhle vetsi tam pak najdes. Staci podedit tridu. + to ma veci jako messaging, IoC, etc...

    DATEL: To by nemelo byt nutne. Do ObservableCollection si to nic neuklada. V ClassFormData mas pro kazdy combobox pro selectedvalue vlastni hodnotu?
    DATEL
    DATEL --- ---
    Ještě s dovolením znovu vypíchnu druhý dotaz, co jsem psal pod ten zdrojový kód ViewModelu, ono to tam nejspíš zapadne.

    Ohledně ItemsSource - vůbec netuším, jak to pracuje interně při bindování, ale měl jsem za to, že to je jen zdroj dat, které zobrazuje ve view. Ale nejspíš si tam nějak interně ukládá i nějaké stavy, asi v tom ObservableCollection? Protože původně jsem myslel, že mi bude stačit pro ItemsSource jen jeden ObservableCollection, který použiju pro více ComboBoxů (výběr ze seznamu studentů). Jenže se to pak chová blbě, při výběru v jiném comboboxu se zruší výběr v předchozím atd. Tj. ve výsledku musím mít pro každý ComboBox sólo ObservableCollection. Skutečně to nelze udělat jedním?
    DATEL
    DATEL --- ---
    DATEL: tak jsem už přišel na to, v čem je problém, holt žádná praxe s WPF - nedošlo mi, že jak v ClassForm.set vytvářím novou instanci FormData, tak že se to nepromítne do bindingu - tj. formulář má nabindovanou instanci FormData z konstruktoru, ale při změně instance v ClassForm.set to už formuláři nijak neřeknu, že by si to měl přebindovat. Takže stačí přidat

    OnPropertyChanged("FormData");

    do toho setteru.
    DATEL
    DATEL --- ---
    EMBI: žádné chyby právě nikde zalogované nejsou. ViewModel vypadá takto:

    public class FormDetailVM : INotifyPropertyChanged
        {
            public ObservableCollection<Student> Students { get; set; }
            public ObservableCollection<Student> Students2 { get; set; }
            public ObservableCollection<Student> Students3 { get; set; }
    
            private ClassForm classForm;
            public ClassForm ClassForm 
            { 
                get
                {
                    return classForm;
                }
                set
                {
                    classForm = value;
                    
                    if (classForm.FormData != null)
                    {
                        FormData = JsonSerializer.Deserialize<ClassFormData>(classForm.FormData);
                    }
                    else
                    {
                        FormData = new ClassFormData();
                    }
                }
            }
    
            private SchoolYearClass schoolYearClass;
            public SchoolYearClass SchoolYearClass 
            {
                get
                {
                    return schoolYearClass;
                }
                set
                {
                    schoolYearClass = value;
                    LoadStudents();
                }
            }
    
            public ClassFormData FormData { get; set; }
    
            public FormDetailVM()
            {
                Students = new ObservableCollection<Student>();
                Students2 = new ObservableCollection<Student>();
                Students3 = new ObservableCollection<Student>();
                FormData = new ClassFormData();
            }
    
            public void saveFormData()
            {
                using (var dbContext = new ApplicationDbContext())
                {
                    dbContext.ClassForms.Attach(ClassForm);
                    ClassForm.FormData = JsonSerializer.Serialize(FormData);
                    dbContext.SaveChanges();
                }
            }
    
            private void LoadStudents()
            {
                Students.Clear();
                Students2.Clear();
                Students3.Clear();
    
                using (var dbContext = new ApplicationDbContext())
                {
                    dbContext.SchoolYearClasses.Attach(schoolYearClass);
    
                    foreach (Student student in schoolYearClass.Students)
                    {
                        if (classForm.Student.Id == student.Id)
                        {
                            continue;
                        }
                        Students.Add(student);
                        Students2.Add(student);
                        Students3.Add(student);
                    }
                }
                
                OnPropertyChanged("Students");
                OnPropertyChanged("Students2");
                OnPropertyChanged("Students3");
            }
    
            public event PropertyChangedEventHandler? PropertyChanged;
    
            private void OnPropertyChanged(string propertyName)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }

    Mimochodem, rovnou položím ještě dotaz ohledně ItemsSource - vůbec netuším, jak to pracuje interně při bindování, ale měl jsem za to, že to je jen zdroj dat, které zobrazuje ve view. Ale nejspíš si tam nějak interně ukládá i nějaké stavy, asi v tom ObservableCollection? Protože původně jsem myslel, že mi bude stačit pro ItemsSource jen jeden ObservableCollection, který použiju pro více ComboBoxů (výběr ze seznamu studentů). Jenže se to pak chová blbě, při výběru v jiném comboboxu se zruší výběr v předchozím atd. Tj. ve výsledku musím mít pro každý ComboBox sólo ObservableCollection. Skutečně to nelze udělat jedním?
    EMBI
    EMBI --- ---
    DATEL: Chybu tam nevidim. Ani podle toho co pises. V debugger output ve Visual Studio nevidis binding error? Mel by tam byt, pokud je nekde problem. Pripadne nasdilej ten ViewModel.
    DATEL
    DATEL --- ---
    Zdravím, .NET a WPF není moje hlavní práce, ale teď v tom dělám jeden menší projekt a zasekl jsem se na jedné věci, ačkoli dle dostupných informací by to mělo být snad správně. Jde o použití ComboBoxu a bindování vybrané hodnoty (tj. ne celého objektu z ItemsResource). Vůbec se mi to do té property nepropisuje :(

    <ComboBox Grid.Row="1" Grid.Column="1" Height="30" Width="150" HorizontalAlignment="Left" VerticalAlignment="Top" 
       ItemsSource="{Binding Students}" DisplayMemberPath="FullName" 
       SelectedValue="{Binding FormData.Q1S1, Mode=TwoWay}" SelectedValuePath="Id" />

    Students je ObservableCollection, FormData.Q1S1 je int. Student obsahuje Id typu int. Co jsem četl, tak tak tohle by mělo fungovat, ale nejdeto. Pochopil jsem to špatně nebo jak by to mělo být správně? Díky moc za pomoc
    TOOMIX
    TOOMIX --- ---
    Kliknutím sem můžete změnit nastavení reklam