Fakturační systém v C# .NET - WPF a User Control

C# .NET Databáze Fakturační systém v C# .NET - WPF a User Control

Minule jsme v tutoriálu řešili lokální databázi a objektový přístup do ní přes Entity Framework. Dnes vytvoříme grafické rozhraní ve WPF. Použijeme dataGridy a comboBoxy. Je vyžadována základní znalost WPF a XAML.

Fakturační systém v C# .NET

Do naší Solution přidáme projekt WPF se jménem View. Bude obsahovat uživatelské rozhraní a nastavíme ho jako StartUp. Dále nastavíme referenci na DB projekt, ve kterém bude krom DB i logická vrstva programu.

Nastavení reference u C# .NET projektu

Návrh formuláře Persons

Budeme vytvářet dva téměř totožné formuláře s větším počtem textboxů. Pro přehlednost a případné další využití na jiném místě v programu si tyto dva formuláře uložíme zvlášť jako User Control.

Do projektu přidáme nový item User Control.

Nový User Control v C# .NET WPF

Celé okno si pomocí kořenového gridu rozdělíme na dva sloupce v poměru 5:3. Do levého vložíme dataGrid a do pravého nový grid pro formulář. DataGrid i grid si pojmenujeme.

DataGrid v C# .NET WPF
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="5*"/>
        <ColumnDefinition Width="3*"/>
    </Grid.ColumnDefinitions>

    <DataGrid Name="dataGridPersons"
    </DataGrid>

    <Grid Name="gridPerson"  Grid.Column="1">
    </Grid>

</Grid>

V gridPerson vytvoříme 2 sloupce s 10 řádky. Do nich vložíme popisky(label) a textBoxy. Do posledního řádku vložíme nový grid s tlačítky.

Účetnictví v C# .NET WPF

Celý kód vypadá následovně.

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="5*"/>
        <ColumnDefinition Width="3*"/>
    </Grid.ColumnDefinitions>

    <DataGrid Name="dataGridPersons" SelectionMode="Single" SelectionUnit="FullRow" IsReadOnly="True" >
    </DataGrid>

    <Grid Name="gridPerson" Grid.Column="1">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="auto"></ColumnDefinition>
            <ColumnDefinition Width="*"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition  Height="auto"/>
            <RowDefinition  Height="auto"/>
            <RowDefinition  Height="auto"/>
            <RowDefinition  Height="auto"/>
            <RowDefinition  Height="auto"/>
            <RowDefinition  Height="auto"/>
            <RowDefinition  Height="auto"/>
            <RowDefinition  Height="auto"/>
            <RowDefinition  />
            <RowDefinition  Height="auto"/>
        </Grid.RowDefinitions>

        <Label Grid.Row="0" >Jméno</Label>
        <Label Grid.Row="1" >Příjmení (firma)</Label>
        <Label Grid.Row="2">IČO</Label>
        <Label Grid.Row="3">DIČ</Label>
        <Label Grid.Row="4">Ulice</Label>
        <Label Grid.Row="5">Město</Label>
        <Label Grid.Row="6">PSČ</Label>
        <Label Grid.Row="7">Email</Label>


        <TextBox Grid.Row="0" Grid.Column="1" Name="txtName" >
        </TextBox>

        <TextBox Grid.Row="1" Grid.Column="1" Name="txtSurname" >
        </TextBox>

        <TextBox Grid.Row="2" Grid.Column="1" Name="txtICO" >
        </TextBox>

        <TextBox Grid.Row="3" Grid.Column="1" Name="txtDIC" >
        </TextBox>

        <TextBox Grid.Row="4" Grid.Column="1" Name="txtStreet" >
        </TextBox>

        <TextBox Grid.Row="5" Grid.Column="1" Name="txtCity" >
        </TextBox>

        <TextBox Grid.Row="6" Grid.Column="1" Name="txtPSC" >
        </TextBox>

        <TextBox Grid.Row="7" Grid.Column="1" Name="txtEmail">
        </TextBox>

        <Grid Name="btns" Grid.Row="10" Grid.Column="0" Grid.ColumnSpan="2">
            <Grid.ColumnDefinitions>
                <ColumnDefinition></ColumnDefinition>
                <ColumnDefinition></ColumnDefinition>
                <ColumnDefinition></ColumnDefinition>
                <ColumnDefinition></ColumnDefinition>
            </Grid.ColumnDefinitions>

            <Button Grid.Column="0" Name="btnNew" >Nový</Button>
            <Button Grid.Column="1" Name="btnEdit" >Upravit</Button>
            <Button Grid.Column="2" Name="btnSave" >Uložit</Button>
            <Button Grid.Column="3" Name="btnDel" >Smazat</Button>
        </Grid>
    </Grid>
</Grid>

Funkčnost tlačítek

Vytvoříme metodu SetPersonButtons, která nám bude zakazovat nebo povolovat tlačítka.

private void SetPersonButtons(bool newPerson, bool edit, bool save, bool delete)
{
    btnNew.IsEnabled = newPerson;
    btnEdit.IsEnabled = edit;
    btnSave.IsEnabled = save;
    btnDel.IsEnabled = delete;
}

Všem tlačítkům registrujeme událost pro kliknutí a voláme metodu SetPersonButtons.

private void btnNew_Click(object sender, RoutedEventArgs e)
{
    SetPersonButtons(false, false, true, false);
}

private void btnEdit_Click(object sender, RoutedEventArgs e)
{
    SetPersonButtons(false, false, true, false);
}

private void btnSave_Click(object sender, RoutedEventArgs e)
{
    SetPersonButtons(true, true, false, true);
}

private void btnDel_Click(object sender, RoutedEventArgs e)
{
    SetPersonButtons(true, true, false, false);
}

Logika dat

V projektu View si vytvoříme třídu Manager. Bude nám sloužit ke správě dat z databáze. Obsahuje kolekci osob typu ObservableCollec­tion. Změny v této kolekci se nám automaticky projeví v datagridu. (pro správnou funkčnost je nutné mít v dataGridu parametr IsReadOnly="True")

public class Manager
{
    private DbInvoiceEntities db = new DbInvoiceEntities();
    private ObservableCollection<Person> persons = new ObservableCollection<Person>();
public ObservableCollection<Person> Persons { get { return persons; } }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        persons.Init(manager);
    }
}

Visual studio nám podtrhlo proměnnou db a vypsalo chybu o chybějící referenci na Entity Framework. Cestu k chybějícím DLL nastavíme stejnou, jakou máme v DB projektu ve složce packages.

Reference ve Visual Studio

Dále musíme v souboru App.config přidat connection string. Najdeme ho v DB projektu.

<connectionStrings>
  <add name="DbInvoiceEntities" connectionString="metadata=res://*/ModelInvoice.csdl|res://*/ModelInvoice.ssdl|res://*/ModelInvoice.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=(LocalDB)\v11.0;attachdbfilename=|DataDirectory|\DbInvoice.mdf;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
</connectionStrings>

Hlavní okno

Do hlavního okna (MainWindow) vložíme TabControl, který nám vytvoří záložky.

<Window x:Class="View.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:localUC="clr-namespace:View"
        Title="InvoiceSys" Height="350" Width="700
        ">
    <TabControl HorizontalAlignment="Stretch"  VerticalAlignment="Stretch" >
        <TabItem Header="Osoby">
            <localUC:PersonsControl x:Name="persons" />
        </TabItem>

        <TabItem Header="Faktury">

        </TabItem>
    </TabControl>
</Window>

Do první záložky "Osoby" vložíme náš UserControl pomocí námi definovaného namespace. Díky tomu designer vidí námi vytvořený UC.

xmlns:localUC="clr-namespace:View"

Nezapomeneme náš PersonsControl pojmenovat.

V MainWindow si vytvoříme instanci třídy Manager. V události Loaded zavoláme metodu Init.

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    persons.Init(manager);
}

Metoda Init v PersonsControl vypadá následovně. DataGridu se nastaví zdroj dat.

public void Init(Manager manager)
{
    this.manager = manager;
    dataGridPersons.ItemsSource = manager.Persons;
}

Návrh formuláře Invoices

Návrh bude v podstatě totožný. Postupujte stejně jako v případě PersonsControl.

Návrh formuláře v C# .NET WPF

Závěrem

Naše dnešní práce by měla vypadat takto.

Formulář pro účetní aplikaci v C# .NET WPF

Vytvořili jsme si dva UserControly, které jsme si přidali do hlavního okna. Data z databáze jsme si zobrazili v DataGridech. V příštím dílu se dostaneme ke stylování formulářů, dataBindingu a validaci dat v TextBoxech.

Než vyjde příští díl, můžete si vyzkoušet implementovat zobrazení dat v TextBoxech po kliknutí na řádek v DataGridu.


 

Stáhnout

Staženo 513x (13.27 MB)
Aplikace je včetně zdrojových kódů v jazyce C#

 

  Aktivity (1)

Článek pro vás napsal Petr Domes (petrds)
Avatar
Programuji v .NET. Ovládám C#, .ASP, WF, WPF, SQL

Jak se ti líbí článek?
Celkem (4 hlasů) :
55555


 



 

 

Komentáře

Avatar
David Čápka
Tým ITnetwork
Avatar
David Čápka:

Fakt pěkný, hlavně ten UserControl a jak jsi to rozdělil na vrstvy. Snad možná jen název třídy Manager mi přijde docela obecný.

Odpovědět 19.3.2014 11:07
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Richard Závodný:

Hezký článek :-)

 
Odpovědět 19.3.2014 13:03
Avatar
N-nojmi
Člen
Avatar
N-nojmi:

Zdravím, at hledám jak hledám tak u seb v projektu nemohu najít connection string jako máš ty.... já našel tak tohle:

Data Source=(LocalDB)\v11.0;AttachDbFilename=C:\Users\tneumann\Downloads\InvoiceSys\InvoiceSys\DbInvoice.mdf;Integrated Security=True

kde si našel zbytek?

<connectionStrings>
  <add name="DbInvoiceEntities" connectionString="metadata=res://*/ModelInvoice.csdl|res://*/ModelInvoice.ssdl|res://*/ModelInvoice.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=(LocalDB)\v11.0;attachdbfilename=|DataDirectory|\DbInvoice.mdf;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
</connectionStrings>
Odpovědět 28.5.2014 14:02
Není hloupých lidí, jen lidí co málo používají google...
Avatar
Odpovídá na N-nojmi
Petr Domes (petrds):

Ale funguje ti to ne? Tvůj connection string je s absolutní cestou, můj s relativní. Ale teď si nevzpomínám, jak jsem toho docílil. V server exploreru mi to píše absolutní cestu.

 
Odpovědět 28.5.2014 14:46
Avatar
N-nojmi
Člen
Avatar
Odpovídá na Petr Domes (petrds)
N-nojmi:

Zasekl jsem se na sekci Logika Dat.

public class BooksManager
    {
        private DbBooksEntities db = new DbBooksEntities();
        private ObservableCollection<Book> persons = new ObservableCollection<Book>();
        public ObservableCollection<Book> Persons { get { return Books } }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            persons.Init(BooksManager);
        }
    }

tohle je můj kód,ale DbBooksEntities mam potržené a píše to:
The type or namespace name 'DbBooksEntities' could not be found (are you missing a using directive or an assembly reference?)
fakt netuším....

Odpovědět 28.5.2014 15:59
Není hloupých lidí, jen lidí co málo používají google...
Avatar
Odpovídá na N-nojmi
Petr Domes (petrds):

v textu mám chybu

tohle nema byt ve tříde Manager ale v MainWindow.xaml

private void Window_Loaded(object sender, RoutedEventArgs e)
 {
     persons.Init(manager);
 }

tvá chyba znamená, že nemáš přidaný using na namespace, ve kterém máš databázi

 
Odpovědět 28.5.2014 16:26
Avatar
Nallim
Člen
Avatar
Odpovídá na Petr Domes (petrds)
Nallim:

Aby šlo použít using namespace, tak musí být přidaná reference na první projekt InvoiceSys.
V projektu View pravým tlačítkem na References -> Add Reference -> Projects a vybrat InvoiceSys.

 
Odpovědět 16. května 4:37
Avatar
Honza67
Člen
Avatar
Honza67:

Ahoj. Poradíte někdo jakým způsobem naprogramovat export dat z gridu (např.přes tlačítko na formuláři) do excelu. dík

 
Odpovědět 5. července 13:19
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.