이번에는 기본 맵 외에 배경이나 나무와 같은 오브젝트를 추가로 찍기위해서 툴을 업데이트했다.


우선 화면밖 1칸내에서도 시작하고 끝낼수있게 여분공간을 추가하고 UI구간을 표시했다.




이제 데코레이션을 꾸미기위한 타일들을 툴에서 골라서 쓸수있게 그부분을 추가하고자 한다.

우선 Tile이라는 클래스를 하나 만들고 싱글톤으로 만듬.

여기에서 mTileData라는 ObservableCollection을 만들어주었다. 이건 거의 List와 비슷하다고 보면된다.

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
namespace DefenceTool
{
    public class Tile
    {
        private string header;
        public string Header
        {
            get { return header; }
            set { header = value; }
        }
        private BitmapImage content;
        public BitmapImage Content
        {
            get { return content; }
            set { content = value; }
        }
    }
    public class Tiles
    {
        public ObservableCollection<Tile> mTileData = new ObservableCollection<Tile>();
 
        private static Tiles instance = null;
        public static Tiles Instance
        {
            get
            {
                if (instance == null)
                    instance = new Tiles();
                return instance;
            }
    }
}
 
cs



그리고 TileModel 클래스를 만들어 Data라는 object는 아까만든 mTileData를 가져온다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
namespace DefenceTool
{
    class TileModel
    {
        object _data;
        public object Data
        {
            get
            {
                if (_data == null)
                    _data = GetData();
                return _data;
            }
        }
 
        private object GetData()
        {
            return Tiles.Instance.mTileData;
        }
    }
}
cs

이 클래스를 만든 이유는 xaml에서 내용을 받아와 출력하기위해서이다.



그리고 새 창을 하나 생성한 후 도구상자에서 ListView를 생성한다.

생성 후 아래와 같이 xaml파일을 작성한다.

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
<Grid>
    // TileModel 클래스를 model이라는 Key값으로 쓰겠다는 것
    <Grid.Resources>
        <local:TileModel x:Key="model" />
    </Grid.Resources>
    
    // model의 Data클래스를 Binding함
    <ListView x:Name="listView" ItemsSource="{Binding Data, Source={StaticResource model}}" SelectionChanged="listView_SelectionChanged">
 
        // ListView의 열을 5줄로 만듬
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <UniformGrid Columns="5"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
 
        // Image의 Source는 Content로, TextBlock의 Text는 Header로 하겠다는 것. (위의 Data 클래스 안의 Content, Header)
        <ListView.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Vertical" VerticalAlignment="Stretch">
                    <Image Source="{Binding Content}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                    <TextBlock Text="{Binding Header}" VerticalAlignment="Center" HorizontalAlignment="Center" Width="100" TextWrapping="Wrap" TextAlignment="Center"/>
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
 
    </ListView>
</Grid>
cs

간단하게 주석을 달아놨다.



이후 새 창의 cs파일에서 디렉토리의 모든 파일을 등록해주면 xaml에서 가지고있는 모든 리스트가 나오게된다.

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
namespace DefenceTool
{
    /// <summary>
    /// TileSelector.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class TileSelector : Window
    {
        private MainWindow mainWindow = null;
        public TileSelector(MainWindow mWindow)
        {
            InitializeComponent();
 
            // 창이 항상 제일위로 가도록
            this.Topmost = true;
            
            mainWindow = mWindow;
 
            // Resource 폴더의 모든파일을 탐색하여 FileInfo 배열에 저장
            DirectoryInfo dirInfo = new DirectoryInfo("Resource");
            FileInfo[] info = dirInfo.GetFiles("*.*", SearchOption.AllDirectories);
 
            // 모든 파일을 mTileData에 Add함.
            foreach (FileInfo f in info)
            {
                Tile t = new Tile();
                t.Header = f.Name;
                t.Content = LoadImage(f.FullName);
                Tiles.Instance.mTileData.Add(t);
            }
        }
 
        // 이미지 주소에서 BitmapImage를 만듬
        private BitmapImage LoadImage(string fileName)
        {
            return new BitmapImage(new Uri(fileName, UriKind.RelativeOrAbsolute));
        }
 
        // ListView의 항목이 바뀌면 index와 선택한 타일의 비트맵, 주소를 메인창으로 넘겨줌
        private void listView_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ListView listView = sender as ListView;
            if(listView != null)
            {
                int index = listView.SelectedIndex;
                Tile t = Tiles.Instance.mTileData[index];
                mainWindow.setTile(t.Content, t.Header);
            }
        }
    }
}
 
cs




메인윈도우에서 아래와 같이 새창을 불러주면 창이 이렇게 뜬다.

1
2
TileSelector tile = new TileSelector(this);
tile.Show();

cs




여기서 이제 길이 아닌 다른것들을 저장할 Dictionary를 만들어 저장 및 삭제 할때에 체크하여 다르게 관리하였다.

1
2
3
4
private Dictionary<Point, string> deco = new Dictionary<Point, string>();
 
deco.Add(mousepos, selectfilename);
deco.Remove(d.Key);
cs


Json 저장시에도 Deco라는 배열을 만들어 json파일에 추가해줬다. Load도 역시 마찬가지.

1
2
3
4
5
6
7
8
9
10
JsonArrayCollection decoArray = new JsonArrayCollection("Deco");
foreach (KeyValuePair<Point, string> d in deco)
{
    JsonObjectCollection jsonPos = new JsonObjectCollection();
    jsonPos.Add(new JsonStringValue("FileName", d.Value));
    jsonPos.Add(new JsonNumericValue("X", d.Key.X));
    jsonPos.Add(new JsonNumericValue("Y", d.Key.Y));
    decoArray.Add(jsonPos);
}
root.Add(decoArray);
cs




그 외에 선택한 이미지를 미리 보여주는 표시창이나, 기본길로 선택을 바꿔주는 버튼을 추가로 생성해주었다.


Posted by misty_
,