원래 TechEd 행사에 맞춰서 공개할려고 했는데, 갑자기 치명적인 버그가 발견되어, 수정해서 주말에 발표한다길레, 금요일에 베타1에 대한 것 다 지우고 기다렸는데, 헛짓했다. 어쩐일로 ms가 친절하게도 silverlight_chainer.exe 라는 파일에 기존 것 찾아서 지워주고 새 버전으로 업그레이드까지 시켜주게 만들어놨다.
그런데 이게 실행해보니 설치중에 문제가 생겨서 중지가 되었다. 난 내가 미리 지워서 문제가 된줄 알았으나 설치와 관련된 도큐먼트를 찾아보니 그런건 아닌 것으로 보였다. 그래서 좀더 자료를 읽어보니 설치시 문제가되는 경우는 수동으로 KB949325 를 제거하라고 한다. 그런데 제어판에가서 설치된 프로그램 목록을 찾아보니 찾는게 안보인다. 그래서, 몇 가지 삽질을 한 후에 겨우 KB949325가 있는 곳을 발견할 수 있었다.
글쎄, 내가 비스타 RTM 나올때부터 사용했는데 어쩐지 HotFix들이 하나도 안보이더만, 이것만 따로 모아 놓고 있었던 것이었다, 사실 이것들까지 설치목록에 우루루 몰려 나올때를 생각하면 아주 잘 한짓인데 나만 모르고 있었던건가 싶다. 혹시 나같이 당황하시는 분이 계실까봐 이 글을 쓰니 참고하시길. 내가 영문 비스타를 쓰고 있고 해서 영문판용 그림으로 링크를 걸었다. 왼쪽 상단의 "View installed updates"를 누르면 된다.
실버라잇2 베타2를 설치할려면 Silverlight 2 Beta 2 Launches를, 나머지 설치시 문제와 관련된 내용은 다음 링크를 참고하시길. Upgrading to Silverlight Tools Beta 2 and Visual Studio 2008 SP1 Beta - BradleyB's WebLog
어제 동적으로 DataGrid에 항목을 추가하는 예제를 작성했는데요, 거기서는 INotifyCollectionChanged가 자체적으로 구현되어 있는 ObservableCollection 을 사용하였습니다.
그러나 이 ObservableCollection은 사용가능한 기능이 우리가 가장 많이 사용하는 List에 비해서는 제한적입니다. 예를 들어 Sort가 필요하다면 List를 사용해야 할 것입니다.
그래서, List가 제공하는 기능을 활용하면서 one-way 바인딩을 통한 동적인 DadaGrid 바운딩이 가능하도록 구현하려고 시도해 보았습니다. 완벽한 구현은 아니지만 참고할 만한 정도는 될것입니다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Specialized;
namespace SilverlightTwoDatagrid2
{
public partial class Page : UserControl
{
MyList<string> list;
public Page()
{
InitializeComponent();
dgOld.ItemsSource = "One Two Three Four Five Six".Split();
btAdd.Click += new RoutedEventHandler(btAdd_Click);
list = new MyList<string>();
list.Add("Hello World!");
dgNew.ItemsSource = list;
}
void btAdd_Click(object sender, RoutedEventArgs e)
{
list.Add(dgOld.SelectedItem.ToString());
}
}
public class MyList<T> : List<T>, INotifyCollectionChanged
{
public event NotifyCollectionChangedEventHandler CollectionChanged;
protected virtual void OnCollectionChanged
(NotifyCollectionChangedEventArgs e)
{
if (CollectionChanged != null)
{
CollectionChanged(this, e);
}
}
public new void Add(T item)
{
base.Add(item);
OnCollectionChanged(new NotifyCollectionChangedEventArgs
(NotifyCollectionChangedAction.Reset));
// 정상적으로는 이벤트 발생시 Add Action을 전송해야 하는데,
// 위치조정이 어려워 Reset Action을 대신 전송했으니 차후에
// 실전 사용시는 적절히 수정해서 사용해야 할 필요가 있습니다.
// OnCollectionChanged((new NotifyCollectionChangedEventArgs
// (NotifyCollectionChangedAction.Add, o, 0));
}
public new void Remove(T item)
{
base.Remove(item);
OnCollectionChanged(new NotifyCollectionChangedEventArgs
(NotifyCollectionChangedAction.Reset));
//
// OnCollectionChanged(new NotifyCollectionChangedEventArgs
// (NotifyCollectionChangedAction.Remove, o, 0));
}
}
}
소스파일첨부:
Dynamic DataGrid (ObservableCollection, INotifyCollectionChanged)
Silverlight/Blend 2008/05/18 19:42아마도 다음 달 초까지는 실버라잇2 베타2가 발표될 것 같습니다. 새로운 기능의 추가는 별로 기대하지 않고 있습니다만, 그래도 베타2에 대해 여전히 기다려지는 건 어쩔수 없네요.
그동안 글을 쓰지 못한 이유중 하나는 갑자기 눈이 안좋아져서 컴퓨터 사용시간을 줄이느라 그만큼 공부도 소흘해져서 입니다. 여러분도 건강에 신경 쓰시기 바랍니다.
이 번 글에서는 동적인 DataGrid의 구현에 대한 것으로, 위의 DataGrid에서 선택된 행의 데이터를 아래 DataGrid에 추가시켜주는 것으로, 자동적으로 add(), remove() 한 것을 반영시킬려면 INotifyCollectionChanged 를 구현해주어야 합니다.
부연 설명을 하자면, binding의 방식은 only once, one-way, two-way 가 있는데, only once는 binding 시를 기준으로 하는 것이고, one-way 는 source에 변화가 생기면 즉시 자동적으로 target에 반영을 시켜주는 방식입니다.
one-way 가 작동하기 위해서는 Collection type에 INotifyCollectionChanged를 구현해주어야 하는데, 이런 번거러움을 제거하기 위해서, 실버라잇에서는 INotifyCollectionChanged가 구현되어 있는 Collection을 제공해주고 있는데 이것이 바로 ObservableCollection입니다.
-------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
namespace SilverlightTwoDatagrid
{
public partial class Page : UserControl
{
ObservableCollection<string> col;
public Page()
{
InitializeComponent();
dgOld.ItemsSource = "One Two Three Four Five Six".Split();
btAdd.Click += new RoutedEventHandler(btAdd_Click);
col = new ObservableCollection<string>();
col.Add("Hello World!");
dgNew.ItemsSource = col;
}
void btAdd_Click(object sender, RoutedEventArgs e)
{
col.Add(dgOld.SelectedItem.ToString());
// throw new NotImplementedException();
}
}
}
예제소스파일첨부:
SilverlightTwoDatagrid2.zip