Diskuze: TreeView WPF C#
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.


sadlomaslox25:28.2.2015 19:07
mas tam zdvojene prirazeni dat. prvni je tu v xamlu
"ItemsSource="{Binding DataContext.Revizes}"" ktere podle me je spatne
protoze se nikdy neodkazujeme pres DataContext (to datacontext tam nema byt)
a druhe mas tu
trvManager.ItemsSource = Revizes;
implementace property Revizes,Objekties a Lhuties me prijde nestastna.
Taky pozor na to jestli se bude jednat o viceuzivatelskou aplikaci (jestli muze byt aplikace spustena vicekrat) tak tim ze nepouzivas UnitOfWork s EntityFrameworkem si ted asi usetris trochu prace ale v pripade tech vice uzivatelu ti tam vzniknou problemy.
Maros2470:28.2.2015 20:10
S WPF začínám, zatím jsem dělal ve WF, ale jinak je mi 45, živit se tím nebudu, jsem revizmí technik elektro a snažím se vytvořit špunt do mezery v Software, ketrý je dostupný,. Učím se tím i Anglish, i když já spíše po Ruski
sadlomaslox25:1.3.2015 0:04
zkus popsat nebo udelat obrazek jak chces aby ten tree view vypadal. bez blizsiho infa te muzu max odkazat na http://blogs.msdn.com/…by-step.aspx
Maros2470:1.3.2015 11:53
Možná toto bude lepší ukázka jak bych to potřeboval udělat:
sadlomaslox25:1.3.2015 17:03
cs
public partial class MainWindow : Window
{
public List<Provozovatel> Data { get; set; }
public MainWindow()
{
InitializeComponent();
Data = new List<Provozovatel>()
{
new Provozovatel()
{
Jmeno = "pepa novak",
Objekty =
{
new Objekt()
{
Nazev = "byt",
Predmet = {"elektroinstalace"}
},
new Objekt()
{
Nazev = "chata",
Predmet = {"hromosvod"}
},
}
},
new Provozovatel()
{
Jmeno = "kamil stastny",
Objekty =
{
new Objekt()
{
Nazev = "byt",
Predmet = {"elektroinstalace", "hromosvod"}
},
}
},
new Provozovatel()
{
Jmeno = "roman obecny",
Objekty =
{
new Objekt()
{
Nazev = "byt",
Predmet = {"hromosvod"}
},
}
},
};
DataContext = this;
}
}
public class Objekt
{
public string Nazev { get; set; }
public List<string> Predmet { get; set; }
public Objekt()
{
Predmet = new List<string>();
}
}
public class Provozovatel
{
public string Jmeno { get; set; }
public List<Objekt> Objekty { get; set; }
public Provozovatel()
{
Objekty = new List<Objekt>();
}
}
xaml
<Window x:Class="wpfTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpfTest="clr-namespace:wpfTest"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.Resources>
<HierarchicalDataTemplate ItemsSource="{Binding Objekty}" DataType="{x:Type wpfTest:Provozovatel}">
<StackPanel Orientation="Horizontal">
<Border Background="Green" Width="8" Height="12" BorderBrush="#00000000"/>
<Label Content="{Binding Jmeno}"/>
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Predmet}" DataType="{x:Type wpfTest:Objekt}">
<StackPanel Orientation="Horizontal">
<Border Background="CornflowerBlue" Width="8" Height="12" BorderBrush="#00000000"/>
<Label Content="{Binding Nazev}"/>
</StackPanel>
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Coral" BorderThickness="0,0,0,2" Margin="5">
<TextBlock Text="{Binding}" />
</Border>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</Grid.Resources>
<TreeView ItemsSource="{Binding Data}" Margin="10,10,0,10" HorizontalAlignment="Left" Width="196" />
</Grid>
</Window>
Maros2470:1.3.2015 17:33
Díky, ale stále nevím jak ta zobrazovaná data načíst přímo z databáze. Tato data jsou uložena v jedné tabulce Revize. Pouze objekt je uložen v tabulce Objekty, ale je vázán na tabulku Revize přes ObjektId. To řešení xaml co jsi mi poslal jsem již také zkoušel z toho odkazu co jsi mi poslal včera.
Maros2470:1.3.2015 17:43
Zkoušel jsem to i takto, ale nevím jak tam dostat třetí položku Objekt.
SqlCommand cmd1 = new SqlCommand("SELECT r.Provozovatel, r.Predmet, r.ObjektId, o.Id, o.TypObjektu FROM Revize r LEFT JOIN Objekty o ON r.ObjektId = o.Id", con);
con.Open();
SqlDataReader dr1 = cmd1.ExecuteReader();
while (dr1.Read())
{
txbProvozovatel.Text = dr1["Provozovatel"].ToString();
TreeViewItem item = new TreeViewItem();
item.Header = dr1["Provozovatel"].ToString();
item.Items.Add(dr1["Predmet"].ToString());
var tree = sender as TreeView;
tree.Items.Add(item);
Maros2470:1.3.2015 17:48
Navíc v tom co jsem před chvílí poslal se mi zobrazuje každý provozovatel tolikrát kolikrát je v databázi, ale potřeboval bych ho zobrazovat jen jednou a pod ním záznamy, které k němu patří.
sadlomaslox25:1.3.2015 18:31
napr.
cs
public partial class MainWindow : Window
{
public object Data { get; set; }
public MainWindow()
{
InitializeComponent();
var objekt1 = new Objekty()
{
ID = 1,
Typ = "Rodiny dum"
};
var objekt2 = new Objekty()
{
ID = 2,
Typ = "Byt"
};
var lhuta1 = new Lhuty()
{
ID = 1,
Lhuta = 7
};
var lhuta2 = new Lhuty()
{
ID = 2,
Lhuta = 14
};
Data = new List<Revize>()
{
new Revize()
{
ID = 1,
Lhuta = lhuta1,
Objekt = objekt1,
Predmet = "elektroinstalace bytu",
Provozovatel = "tomas novak"
},
new Revize()
{
ID = 2,
Lhuta = lhuta2,
Objekt = objekt1,
Predmet = "hromosvod",
Provozovatel = "tomas novak"
},
new Revize()
{
ID = 3,
Lhuta = lhuta1,
Objekt = objekt2,
Predmet = "hromosvod",
Provozovatel = "roman lesni"
},
new Revize()
{
ID = 4,
Lhuta = lhuta1,
Objekt = objekt1,
Predmet = "hromosvod",
Provozovatel = "roman lesni"
}
}.GroupBy(key => key.Provozovatel).Select(o => new {Key = o.Key, Value = o.GroupBy(u => u.Objekt.Typ)});
DataContext = this;
}
}
public class Revize
{
public int ID { get; set; }
public string Provozovatel { get; set; }
public string Predmet { get; set; }
public Lhuty Lhuta { get; set; }
public Objekty Objekt { get; set; }
}
public class Lhuty
{
public int ID { get; set; }
public int Lhuta { get; set; }
}
public class Objekty
{
public int ID { get; set; }
public string Typ { get; set; }
}
a xaml
<Window x:Class="wpfTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TreeView ItemsSource="{Binding Data}" Margin="10,10,0,10" HorizontalAlignment="Left" Width="497" >
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Value}">
<StackPanel Orientation="Horizontal">
<Border Background="Green" Width="8" Height="12" BorderBrush="#00000000"/>
<Label Content="{Binding Key}"/>
</StackPanel>
<HierarchicalDataTemplate.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding}">
<StackPanel Orientation="Horizontal">
<Border Background="CornflowerBlue" Width="8" Height="12" BorderBrush="#00000000"/>
<Label Content="{Binding Key}"/>
</StackPanel>
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Coral" BorderThickness="0,0,0,2" Margin="5">
<TextBlock Text="{Binding Predmet}" />
</Border>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Grid>
</Window>
Maros2470:1.3.2015 21:55
Možná jsem tupý. Ale nechápu to, že se načítá string: Predmet = "elektroinstalace Bytu",.
Je to vložený ručně, ale já potřebuji dostat data z databáze. Pro
jistotu uvedu i třídy, možná si nerozumíme:
Class Objekty:
namespace Revize_2
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial;
[Table("Objekty")]
public partial class Objekty
{
public Objekty()
{
Revizes = new HashSet<Revize>();
}
public int Id { get; set; }
[StringLength(50)]
public string TypObjektu { get; set; }
public virtual ICollection<Revize> Revizes { get; set; }
}
}
Class Lhuty:
namespace Revize_2
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial;
[Table("Lhuty")]
public partial class Lhuty
{
public Lhuty()
{
Revizes = new HashSet<Revize>();
}
public int Id { get; set; }
public int Lhuta { get; set; }
public virtual ICollection<Revize> Revizes { get; set; }
}
}
Class Revize:
namespace Revize_2
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial;
[Table("Revize")]
public partial class Revize
{
[Key]
[Column(Order = 0)]
public int Id { get; set; }
[Key]
[Column(Order = 1)]
public string Provozovatel { get; set; }
[Key]
[Column(Order = 3)]
public string Adresa { get; set; }
[Key]
[Column(Order = 4)]
public string Odkaz { get; set; }
[Key]
[Column(Order = 5, TypeName = "date")]
public DateTime DatumRevize { get; set; }
[Key]
[Column(Order = 6, TypeName = "date")]
public DateTime NaslednaRevize { get; set; }
[Key]
[Column(Order = 7)]
[StringLength(10)]
public string Status { get; set; }
[Key]
[Column(Order = 8)]
[StringLength(13)]
public string CisloRevize { get; set; }
[StringLength(8)]
public string Ic { get; set; }
[Key]
[Column(Order = 9)]
public string Predmet { get; set; }
[Key]
[Column(Order = 11)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int LhutaId { get; set; }
[Key]
[Column(Order = 12)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ObjektId { get; set; }
public virtual Lhuty Lhuty { get; set; }
public virtual Objekty Objekty { get; set; }
}
}
cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Data.Entity;
using System.Collections.ObjectModel;
using System.Runtime.CompilerServices;
using System.ComponentModel;
using Revize_2.Models;
using System.Data.SqlClient;
namespace Revize_2
{
/// <summary>
/// Interakční logika pro MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged
{
private Objekty obj = new Objekty();
private Lhuty lhuty = new Lhuty();
private Revize revize = new Revize();
public SqlConnection con = new SqlConnection(@"Data Source=(LocalDB)\v11.0;AttachDbFilename=g:\C#\Programování\2013\WPF\Revize 2\Revize 2\bin\Debug\Revize_2.mdf;Integrated Security=True");
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
private readonly ManagerDbContext _context = new ManagerDbContext();
private IEnumerable<Lhuty> _lhuties;
public IEnumerable<Lhuty> Lhuties
{
get
{
return new ObservableCollection<Lhuty>(_context.Lhuties);
}
set
{
_lhuties = value;
OnPropertyChanged("Lhuties");
}
}
private IEnumerable<Objekty> _objekties;
public IEnumerable<Objekty> Objekties
{
get
{
return new ObservableCollection<Objekty>(_context.Objekties);
}
set
{
_objekties = value;
OnPropertyChanged("Objekties");
}
}
private IEnumerable<Revize> _revizes;
public IEnumerable<Revize> Revizes
{
get
{
return new ObservableCollection<Revize>(_context.Revizes.Include(o => o.Objekty));
}
set
{
_revizes = value;
OnPropertyChanged("Revizes");
}
}
public Revize _currentSelectedRevize { get; set; }
public Revize CurrentSelectedRevize
{
get
{
return _currentSelectedRevize;
}
set
{
_currentSelectedRevize = value;
OnPropertyChanged("CurrentSelectedRevize");
}
}
#region INotifyPropertyChanged Implementing
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
#region CRUD Method
private void AddNewRevize(Revize revize)
{
_context.Revizes.Add(revize);
_context.SaveChanges();
}
private void UpdateCurrentRevize(Revize revize)
{
var revizeToUpdate = _context.Revizes.SingleOrDefault(e => e.Id == revize.Id);
if (revizeToUpdate == null) return;
revizeToUpdate.Provozovatel = revize.Provozovatel;
revizeToUpdate.ObjektId = revize.ObjektId;
revizeToUpdate.LhutaId = revize.LhutaId;
revizeToUpdate.Predmet = revize.Predmet;
revizeToUpdate.Odkaz = revize.Odkaz;
revizeToUpdate.Status = revize.Status;
revizeToUpdate.Adresa = revize.Adresa;
revizeToUpdate.CisloRevize = revize.CisloRevize;
revizeToUpdate.DatumRevize = revize.DatumRevize;
revizeToUpdate.NaslednaRevize = revize.NaslednaRevize;
revizeToUpdate.Ic = revize.Ic;
_context.SaveChanges();
}
private void DeleteCurrentRevize(Revize revize)
{
var employeeToUpdate = _context.Revizes.SingleOrDefault(e => e.Id == revize.Id);
_context.Revizes.Remove(employeeToUpdate);
_context.SaveChanges();
}
#endregion
private void btnClose_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
//Close();
App.Current.Shutdown();
}
private void btnExit_Click(object sender, RoutedEventArgs e)
{
//Close();
App.Current.Shutdown();
}
private void btnAbout_Click(object sender, RoutedEventArgs e)
{
About ab = new About();
ab.Show();
}
private void btnHelp_Click(object sender, RoutedEventArgs e)
{
HelpWindow help = new HelpWindow();
help.Show();
}
}
}
}
Ve WF to je V pohodě, ale ve WPF nezvládám kontrolku TreeView. Chci se dostat v technologii dále a to to zatím vůbec neuvažuji o MVVM.
sadlomaslox25:2.3.2015 9:42
presne tak tady si nejak nerozumime protoze ted nevim co teda nechapes nebo ti nejde. xaml je jasny xaml by mel byt tak jak sem poslal. pa bud to
1. oddelas binding na treeview z xamlu a budes to posilat z kodu misto
trvManager.ItemsSource = Revizes;
tak
trvManager.ItemsSource = Revizes.GroupBy(key =>
key.Provozovatel).Select(o => new {Key = o.Key, Value = o.GroupBy(u =>
u.Objekty.TypObjektu)});
2. do tridy mainform pridas property object DataForTree, v xamlu treeview nabindujes na tuto property a v kodu do ni nacpes Revizes.GroupBy(key => key.Provozovatel).Select(o => new {Key = o.Key, Value = o.GroupBy(u => u.Objekty.TypObjektu)});
zadne problemy s databazi nevidim protoze pouzivas EF ktere podporuje lazyLoading a navigation path takze nevim co je teda za problem.
Maros2470:2.3.2015 9:57
Já už jsem z toho tak zblbnutý, už jsem vyzkoušel kdeco, takže se
nezlob, že tě zase otravuji, ale nerozumím tady tomu:
2. do tridy mainform pridas property object DataForTree, v xamlu treeview
nabindujes na tuto property a v kodu do ni nacpes Revizes.GroupBy(key =>
key.Provozovatel).Select(o => new {Key = o.Key, Value = o.GroupBy(u =>
u.Objekty.TypObjektu)});
Maros2470:2.3.2015 10:00
Už mi to chodí!!!!!!!!!!!!!! Díky moc!!!!!!!!!!!!!!!
sadlomaslox25:2.3.2015 10:02
public partial class MainWindow : Window, INotifyPropertyChanged
{
...
private object _dataForTree;
public object DataForTree
{
get
{
return _dataForTree;
}
set
{
_dataForTree= value;
OnPropertyChanged("DataForTree");
}
}
...
private void DeleteCurrentRevize(Revize revize)
{
var employeeToUpdate = _context.Revizes.SingleOrDefault(e => e.Id == revize.Id);
_context.Revizes.Remove(employeeToUpdate);
_context.SaveChanges();
DataForTree=Revizes.GroupBy(key => key.Provozovatel).Select(o => new {Key = o.Key, Value = o.GroupBy(u => u.Objekty.TypObjektu)});
///trvManager.ItemsSource = Revizes;
}
...
}
xaml
...
<TreeView ItemsSource="{Binding DataForTree}" Margin="10,10,0,10" HorizontalAlignment="Left" Width="497" >
...
Maros2470:2.3.2015 10:20
Ještě jednou díky. Teď nastane další etapa a to SelectItem. Na to už, ale možná příjdu.
Maros2470:2.3.2015 12:46
Promiň, že tě ještě otravuji. Marně hledám na netu jak provést SelectedItem. Potřebuji po kliknutí na item, aby se mi vybraná data načetla data do textboxů. Zatím se mi podařilo zjistit jak načíst index, ale to co potřebuji jsem nikde zatím nenašel. Moc díky za radu.
Jan Vargovský:2.3.2015 12:50
Tohle řeš skrz binding. Nabinduj si SelectedItem na vlastnost v code-behind a textboxy si nabinduj na tu vlastnost, která odkazuje na SelectedItem.
Maros2470:2.3.2015 13:17
Už jsem z toho dočista magor. Můžeš mi to prosím blíže vysvětlit. V kódu mám zatím toto:
public Revize _currentSelectedRevize { get; set; }
public Revize CurrentSelectedRevize
{
get
{
return _currentSelectedRevize;
}
set
{
_currentSelectedRevize = value;
OnPropertyChanged("CurrentSelectedRevize");
}
}
Díky
Jan Vargovský:2.3.2015 13:33
Todle nemá s WPF nic společného. Projdi si jak se píše v C# vlastnost. V tomto případě se podívej co ti vygeneruje code snippet "propfull".
Maros2470:2.3.2015 15:19
Už mám asi vygumovanou hlavu. Dva dny se snažím TreeView rozchodit a už mi to vůbec nemyslí.
Maros2470:2.3.2015 18:35
Asi to vzdám a použiji DataGrid, s ním nemám problém, akorát se do té aplikace moc nehodí. I tak díky za rady.
sadlomaslox25:2.3.2015 22:38
kdyz tam me posli pres pm kontakt na skype ti to muzu ukazat na skype
Zobrazeno 26 zpráv z 26.