원래 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

Posted by 한누리

어제 동적으로 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)); } } }

소스파일첨부:

Posted by 한누리

아마도 다음 달 초까지는 실버라잇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();
        }
    }
}

예제소스파일첨부:

Posted by 한누리