IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Utilisation d'une grille en tant que carte [Débutant]


Sujet :

C#

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2018
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 22
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2018
    Messages : 16
    Points : 25
    Points
    25
    Par défaut Utilisation d'une grille en tant que carte
    Bonjour, en ce moment je travaille sur un projet Xaml, C# où je dois créer un Master Detail.
    Pour ma part, j'ai pris Clash of clans (un jeu mobile) comme sujet. Dans ce jeu, le joueur possède un village qu'il améliore et peut aussi attaquer le village des autres joueurs etc.
    Une partie de mon application doit proposer aux utilisateurs de créer leur propre plan et de le partager.

    J'ai donc une vue permettant de créer son plan mais une partie me pose problème.
    J'aimerais avoir une carte (comme celle du jeu) qui serait semblable à une grille et un menu déroulant contenant des images des bâtiments disponibles.
    Ainsi, il suffirait de faire un glissé déposé d'une image sur la grille pour faire le plan etc.

    Dans le code behind, j'ai prévu de faire un tableau ou bien une matrice contenant les bâtiments, leur taille ainsi que leur position pour pouvoir recharger ce dernier dans l'application.
    Seulement, je ne vois pas comment faire pour que l'application puisse voir qu'une image à été posé sur la grille, puis qu'elle mette les informations utiles dans la classe correspondante.

    Je précise que je suis un débutant (mais si c'est déjà marqué dans le préfixe). Pour vous donner un exemple :
    - le mode édition du jeu possède le même principe (pour ceux qui connaissent COC)
    - un site qui se nomme "clash of clans builder" propose la même fonctionnalité : http://clashofclansbuilder.com/build?latest=true

    Merci d'avance
    Ps: je vous met une capture d'écran du sketch de la vue de création du plan

    Nom : Ajout_Plan.PNG
Affichages : 213
Taille : 29,7 Ko

  2. #2
    Membre chevronné
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 905
    Points : 1 923
    Points
    1 923
    Par défaut
    Citation Envoyé par jpagnol Voir le message
    Dans le code behind
    Non, pas dans le code behind, tu es en WPF, pas en WinForms. Le code behind des composants ne devrait gérer que le comportement spécifique du composant, en lui-même il ne devrait pas par exemple manipuler les données ou lancer des traitements. Les données à gérer sont le domaine du Model et du ViewModel, pas dans la vue ; le ViewModel est ensuite inséré dans la vue par le DataContext.

    Tu prévois de partager les plans, cela signifie que tu vas devoir persister ton plan d'un manière ou d'une autre (fichier ou base de données), peut-être que tu pourrais réfléchir à la façon dont tu veux faire cette sauvegarde et au modèle de données auquel ça va correspondre.

    Quand à la fonctionnalité que tu veux implémenter cela passe par du drag 'n drop, qui déclenchera une commande demandant la modification du modèle, ce qui provoquera ensuite une mise à jour du modèle de vue puis de la vue.

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2018
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 22
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2018
    Messages : 16
    Points : 25
    Points
    25
    Par défaut
    Merci pour ces précisions mais, est-ce qu'il serait possible de m'indiquer la marche à suivre pour mettre en place un drag and drop même simple ?

    J’apprécierais grandement, merci d'avance.

  4. #4
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 442
    Points
    4 442
    Par défaut
    Citation Envoyé par jpagnol Voir le message
    Merci pour ces précisions mais, est-ce qu'il serait possible de m'indiquer la marche à suivre pour mettre en place un drag and drop même simple ?

    J’apprécierais grandement, merci d'avance.
    La marche (démarche veux-Tu dire certainement),eh bien elle sera semée d’embûches qu'il va falloir surmonter comme débutant.
    Voici les points importants (illustré par l'exemple code ci-après)
    1/ Drag Drop: l'interface Drag Drop avec "feedback" visuel Pour l'user est inutilisable .
    Car étant implémentée en Wpf par UIement (et ses descendants les Controls) ,de même que dans les Winforms Classiques) on doit recourir à du code behind dans la Vue Model.
    Le substitut de cela dans MVVM c'est le Pattern Command sans "feedback" visuel.

    1/ MVVM veut dire tout est dirigé par les données c.à.d le ViewModel par suite tu dois utiliser le "binding" à fond et conjointement le pattern Command.

    1/ le seul Control de type tableau(matrice 2D) tout fait en WPF est UniformGrid:
    - il faut fournir nombre de Row & Column

    3/ Un control ItemsControl (ou un ListBox si tu veux récupérer un élément sélectionné) fera l’affaire & sera "bindé" à ta liste de DataItems du V.M.
    Sa prop itemsPanel sera ajusté pour recevoir un UniformGrid ce qui affichera ta liste DataItems sous forme d'array 2d.

    4/ Les data :comme tu envisages de sauvegarder chaque DataItem y compris son Image droppée dessus , il faut disposer d'une prop Uri dans celui-ci
    Uri est un objet "barbare" en Wpf qui remplace le "path file" de type string des Winforms classiques.
    l'objet Uri encapsule le chemin d’accès à ton image(quelque part dans un dossier) .
    On ne sauvegarde qu'un seul objet Uri peu volumineux pour plusieurs DataItems au lieu de memoriser un bitmap / DataItem.
    Gain de mémoire et d'espace .

    3/ Pattern Command :2 API sont utilisés dans l'exemple code
    - le premier natif en Wpf implémente l'interace ICommand uniquement pour le Control Button & cousins (checkbox,radiobutton).
    Il est utilisable même dans un DataTemplate .
    C'est celui là qui est utilisé pour l'ItemsControl qui représente la "Grille".
    - le deuxieme qui reside dans l'Assembly System.Windows.Interactivity qu'il faut référencer implémente l'interace ICommand pour tous les Controls et tous les Events ..
    Son defaut majeur est qu'il ne fonctionne pas dans un DataTemplate
    C'est celui là qui est utilisé pour le Menu avec les Controls Images "tapé" directement à la mano.

    4/ Dernier point le "barbare" Uri de l'image droppée n'est pas facile d'accès par code et il est récupéré via Un Converter (en fait il égal à BitmapSource.ToString().
    Encore un arcane Wpf.
    Moyen cela voici l'exemple code avec 7 pauvres bitmap.

    class DataItem(dossier Data)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    namespace WpfDragDropGrille.Data
    {
        public class BaseModel : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
            public void Raise(string nameProp)
            {
                PropertyChangedEventHandler h = PropertyChanged;
                if (h != null)
                    h(this, new PropertyChangedEventArgs(nameProp));
     
            }
        }
    }
    using System;
    using System.Collections.ObjectModel;
    namespace WpfDragDropGrille.Data
    {
        public class DataItem : BaseModel
        {
            public static double Side { get; set; }
            public DataItem()
            {
                Side = 75.0;
            }
            private int id;
            public int Id
            {
                get { return id; }
                set { id = value; Raise("Id"); }
            }
            private string nom;
            public string Nom
            {
                get { return nom; }
                set { nom = value; Raise("Nom"); }
            }
            private Uri uriPhoto = new Uri("pack://application:,,,/WpfDragDropGrille;component/Images/BitmapX.bmp", UriKind.RelativeOrAbsolute);
            public Uri UriPhoto
            {
                get { return uriPhoto; }
                set { uriPhoto = value; Raise("UriPhoto"); }
            }
     
        }
     
    }
    class Converter(dossier Converters)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    using System;
    using System.Windows.Data;
    using System.Windows.Media.Imaging;
     
    namespace WpfDragDropGrille.Converters
    {
        class ImageToUriConverter:IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                BitmapSource bmpSrc = value as BitmapSource;
     
                Uri uri = null;
                if (bmpSrc != null)
                {
                    uri =new Uri( bmpSrc.ToString(),UriKind.RelativeOrAbsolute);
                }
                return uri;
            }
     
            public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }
    }
    class ListDataItemVM (dossier ViewModel)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    using System;
    using System.Collections.ObjectModel;
    using WpfDragDropGrille.Data;
    using System.Windows.Input;
    namespace WpfDragDropGrille.ViewModel
    {
        class ListDataItemVM:BaseModel
        {
            Cursor cursorDrag = Cursors.Cross;
            public ListDataItemVM()
            {
                dataItems = new ObservableCollection<DataItem>();
                LoadDataItems();
     
                CmdGetData = new RelayCommand<object>(GetData, CanGetData);
                CmdDrop = new RelayCommand<object>(SetDropData, CanSetDropData);
            }
            #region Proprietes
     
            private ObservableCollection<DataItem> dataItems;
            public ObservableCollection<DataItem> DataItems
            {
                get { return dataItems; }
                set { dataItems = value; Raise("DataItems"); }
            }
            // props  rows et cols
            public int Rows
            {
                get { return DataItems.Count / 4; }
            }
            public int Columns
            {
                get { return DataItems.Count / 3; }
            }
     
            #endregion Proprietes
     
            #region Commandes
            public ICommand CmdGetData { get; set; }
            private object data = null;
            public void GetData(object parameter)
            {
                data = parameter;
            }
            public bool CanGetData(object parameter)
            {
                return true;
            }
            public ICommand CmdDrop { get; set; }
            public void SetDropData(object parameter)
            {
                if (data != null)
                {
                    Uri newUri = (Uri)data;
     
                    DataItem item = (DataItem)parameter;
                    item.UriPhoto = newUri;
                }
            }
            public bool CanSetDropData(object parameter)
            {
                return true;
            }
            #endregion Commandes
     
            #region Methodes Privees
     
            public void LoadDataItems()
            {
                double x, y;
                int nbElem = 12;
                int row = nbElem /4; int col = nbElem /3;
     
                int numElem = 1;
                x = 0.0; y = 0.0;
                for (int i = 1; i < row + 1; i++)
                {
                    for (int j = 1; j < col + 1; j++)
                    {
                       DataItem it = new DataItem() 
                        {
                            Id = numElem, 
                            Nom = "Item" + i.ToString() + j.ToString(),
                            UriPhoto =
                            new Uri("pack://application:,,,/WpfDragDropGrille;component/Images/BitmapX.bmp")
                        };
                        dataItems.Add(it);
                        x += DataItem.Side;
                        numElem++;
                    }
                    x = 0;
                    y += DataItem.Side;
                }
     
            }
           #endregion Methodes Privees
        }
    }
    class ControlGrille un UserControl (dossier Views)

    Code XAML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    <UserControl x:Class="WpfDragDropGrille.Views.ControlGrille"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:data="clr-namespace:WpfDragDropGrille.Data"
                 xmlns:vm="clr-namespace:WpfDragDropGrille.ViewModel"
                 xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
                 xmlns:views="clr-namespace:WpfDragDropGrille.Views"
                 xmlns:converters="clr-namespace:WpfDragDropGrille.Converters"
     
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300"
                 >
        <UserControl.DataContext>
            <vm:ListDataItemVM/>
        </UserControl.DataContext>
        <UserControl.Resources>
            <converters:ImageToUriConverter x:Key="cnv"/>
     
            <!--un bouton au lieu d'un control Image qui n'implemente as ICommand -->
            <!-- sa prop Command est "bindé" à DataContext de l'ancetre c.à.d le VM -->
            <!-- le 2 eme DataContext du Parameter vise  la prop UriPhoto
            attention au DataContext -->
     
            <DataTemplate   
                x:Key="templateDataItem" 
                DataType="{x:Type data:DataItem}">
                <Grid>
                    <TextBlock Text="{Binding Nom}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
     
                    <Button x:Name="dest"   Width="50" Height="50"
                        Command="{Binding 
                        Path=DataContext.CmdDrop, 
                        RelativeSource={RelativeSource Mode=FindAncestor, 
                                              AncestorType={x:Type UserControl}}}" 
                        CommandParameter="{Binding ElementName=dest,
                        Path=DataContext}"
                           >
                        <Button.Background>
                            <ImageBrush ImageSource="{Binding UriPhoto}"/>
                        </Button.Background>
                        <Button.ToolTip >
                            <TextBlock Text="Clik to Select Cell Drop"/>
                        </Button.ToolTip>
                    </Button>
                </Grid >
            </DataTemplate>
        </UserControl.Resources>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="auto"></RowDefinition>
                <RowDefinition Height="auto" ></RowDefinition>
            </Grid.RowDefinitions>
     
            <StackPanel Grid.Row="0">
                <!--pour le Menu ses MenuItems peuvent etre des Control Images -->
                <!--comme il y  a en peu(ici 6) je n'utilise pas le Binding avec une liste d'images -->
                <!--& En sus j'utilise la reference à l'asembly System.Windows.Interactivity -->
                <!--qui permet d'emettre des commandes pour n'imorte quel control Wpf  -->
                <!--contrairement au Pattern ICommand reervé au seul  Button  -->
                <Menu >
                    <Menu.ToolTip>
                        <TextBlock Text="Clic to Select an Image to Drag"></TextBlock>
                    </Menu.ToolTip>
                    <Image x:Name="imgSrc1" Width="25" Height="25" Source="/Images/bitmap1.bmp"
                         >
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="MouseDown">
                                <i:InvokeCommandAction 
                                    Command="{Binding Path=CmdGetData}"
                                    CommandParameter="{Binding ElementName=img1, Path=Source,Converter={StaticResource cnv}}"/>
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                    </Image>
                    <Image x:Name="imgSrc2" Width="25" Height="25" Source="/Images/bitmap2.bmp">
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="MouseDown">
                                <i:InvokeCommandAction 
                                    Command="{Binding Path=CmdGetData}"
                                    CommandParameter="{Binding ElementName=img2, Path=Source,Converter={StaticResource cnv}}"/>
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                    </Image>
                    <Image x:Name="imgSrc3" Width="25" Height="25" Source="/Images/bitmap3.bmp">
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="MouseDown">
                                <i:InvokeCommandAction 
                                    Command="{Binding Path=CmdGetData}"
                                    CommandParameter="{Binding ElementName=img3, Path=Source,Converter={StaticResource cnv}}"/>
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                    </Image>
                    <Image x:Name="imgSrc5" Width="25" Height="25" Source="/Images/bitmap5.bmp">
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="MouseDown">
                                <i:InvokeCommandAction 
                                    Command="{Binding Path=CmdGetData}"
                                    CommandParameter="{Binding ElementName=img5, Path=Source,Converter={StaticResource cnv}}"/>
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                    </Image>
                    <Image x:Name="imgSrc6" Width="25" Height="25" Source="/Images/bitmap6.bmp">
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="MouseDown">
                                <i:InvokeCommandAction 
                                    Command="{Binding Path=CmdGetData}"
                                    CommandParameter="{Binding ElementName=img6, Path=Source,Converter={StaticResource cnv}}"/>
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
     
                    </Image>
                </Menu>
            </StackPanel>
            <StackPanel  Grid.Row="1">
                <ItemsControl
                    x:Name="ListBox2" 
                    ItemTemplate="{StaticResource templateDataItem}"
                    ItemsSource="{Binding DataItems}"
                     >
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate >
                            <UniformGrid 
                                IsItemsHost="true"
                                Rows="{Binding Rows}" Columns="{Binding Columns}"  >
                            </UniformGrid> 
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                </ItemsControl>
            </StackPanel>
        </Grid>
    </UserControl>
    pas de code behind.cs

    code xaml du form User :

    Code XAML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <Window x:Class="WpfDragDropGrille.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
           xmlns:views="clr-namespace:WpfDragDropGrille.Views"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
            <views:ControlGrille/>
        </Grid>
    </Window>
    pas de code behind.cs

    bon code.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Sogenactif] Utiliser une variable en tant que transaction id Sogenactif
    Par danieldou dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 0
    Dernier message: 15/02/2016, 17h06
  2. Utiliser une Class en tant que type générique
    Par shaiHulud dans le forum Langage
    Réponses: 6
    Dernier message: 27/11/2015, 14h20
  3. Android Studio utiliser une classe en tant que bibliothèque
    Par ChPr dans le forum Android Studio
    Réponses: 0
    Dernier message: 17/11/2015, 23h06
  4. utilisation d"une variable en tant que motif de
    Par bilout dans le forum Langage
    Réponses: 4
    Dernier message: 26/03/2006, 20h19
  5. [FTP] Définir une variable en tant que constante
    Par Anduriel dans le forum Langage
    Réponses: 2
    Dernier message: 15/01/2006, 11h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo