퇴근5분전



WPF용 플렉스 그리드에서 콤보박스형태로 데이타를 나타나게 하려면...

해당 컬럼에 ValueConverter에 
1.  new ColumnValueConvert(    [] 타입 , false );
2.  new ColumnValueConvert(  Dictionary  );
   ? 여기서 문제가 발생

  코드값 Y  , Name 값 Y인경우... 
 dic["Y" ] = "Y"; 로 해서 바인딩 시켰을 시 문제가 생긴다.

이를 해결하기 위한 방법을 아래 설명하였다.

( 삽질 신공으로 투자한 시간은 2일정도 된것 같음.. )
덕분에 바인딩을 모두 다시 공부했다...

/********************************************************************************************************

플렉스 그리드에서 기본 제공되는 컨버터로는 해결이 안된다.
예제 샘플을 보면 Dictionary로 선언해서 객체에서 받아서 넘겨주면
Key를 int로 검색하여 코드의 경우 문자열을 코드로 사용하는 경우
문제시 된다. : 예외로 지정한 캐스팅이 어쩌고 저쩌고...

이를 해결하기 위한 방법은 아래처럼 하면 된다.

1. AutoGenerateColumns  = false를 준다. ( true일경우 똑같은 컬럼들이 새로 생성된다 )
2. ItemSource 속성에 {Binding} 설정
3. DataContext에 데이타 테이블을 넘겨준다.
4. 컬럼.Binding = new Binding( Path명 ); 으로 설정해준다.
5. 컬럼.ValueConverter 에 새로 만든 UsedColumnValueConvert를 넘겨주자.
 : 컨버터에는 코드키와 값을 셋팅한 Dictionary<object, string>으로 구성해서 넘겨준다.

**********************************************************************************************************/
.cs 


    DataTable dt = new DataTable();

                dt.Columns.Add("NO");
                dt.Columns.Add("YN");

                dt.Rows.Add(1, "Y");
                dt.Rows.Add(1, "N");

                Dictionary<object, string> lst = new Dictionary<object, string>();

                lst["Y"] = "Y";
                lst["N"] = "N";
                lst["K"] = "K";

                Fx.DataContext = dt;
                Fx.AutoGenerateColumns = false;

                   Column c = new Column();
                c.Binding = new Binding("NO");

                Column c1 = new Column();
                c1.Binding = new Binding("YN");

                Fx.Columns.Add(c);
                Fx.Columns.Add(c1);

                Fx.Columns[1].ValueConverter = new UsedColumnValueConverter(lst);

// Fx.Rows.Add <== 하면 데이타 안늘어남. 참 뭐같음.
// 고로 원본을 꺼내 직접 Add 시켜야 함. 


                for (int i = 201001; i < 201012; i++)
                {
                    DataRow dr = dt.NewRow();
                    foreach (Column c in dt.Columns)
                    {
                        dr[c.ColumnName] = 0;
                    }
                    dr[0] = i;

                    dt.Rows.Add(dr);
                }
             
              //  Fx.Rows.Add(new Row());    // Row증가가 되지 않음.



.xaml

<c1Flex:C1FlexGrid  Grid.Row="1" Grid.Column="2" Name="Fx"  ItemsSource="{Binding}"  >
c1Flex:C1FlexGrid>



여기서 필요한건 새로 만든 UsedColumnValueConverter

 public class UsedColumnValueConverter : IValueConverter, IEditValueConverter
   
{
        IDictionary<object, string> dic = null;
        bool Ex = true;

        public UsedColumnValueConverter(IDictionary<object, string> idic)
        {
            dic = idic;
        }

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (dic.Keys.Contains(value))
                return dic[value];
            else
                return value;
             //
return null;     //널값 주면 값이 사라져버림.

        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return value;

           // return DependencyProperty.UnsetValue;
        }

        public bool Exclusive
        {
            get { return Ex; }
        }

        public ICollection Values
        {
            get {
              return  dic.Values.ToList();
           
            }
        }
    }



PS : 컨트롤에 대한 스터디 시간이 없으므로 다른 컨트롤로 교체됨.

'# 3) .Net ( Vs 2008 ) > WPF' 카테고리의 다른 글

WPF Textbox의 Numeric!  (0) 2015.09.05
WPF 에서 Keyboard 입력 하기 Winfom SendKeys 같은..  (0) 2011.09.08
IValueConverter 사용 데모  (0) 2010.09.06
WPF 쓰레드 ( 프로그래스바 )  (0) 2010.08.10
[WPF] Tab 순환코드  (0) 2010.07.27


 오늘 만든 폼에 사용해야 될 객체중 하나로 사용해본 후 기록함.

    // 정의
    public interface IValueConverter
    {
             object Convert(object value, Type targetType, object parameter, CultureInfo culture);
             object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture);
    }

 xaml에서 표현하는 컨트롤이 checkbox이고  내부 데이타(DB코드값)는 숫자타입 0 : false, 0 이 아니면 true라고 한다면...

[ValueConversion( typeof(int), typeof(bool))]
 public class IntToBoolenValueConverter : IValueConverter
    {
        #region IValueConverter 멤버
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            int i = System.Convert.ToInt32(value);
            return i != 0;
        }
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            bool b = System.Convert.ToBoolean(value);
            return b ? 1 : 0;
        }
        #endregion
    }

위와 같이 구현한다.

추가:  ValueConversion 속성순서처럼
int -> bool은 convert메서드에서
bool -> int는 ConvertBack 메서드에서 각각 구현순서로 기억하면 편하다
.




< 아래 소스 실행화면 >


/********************************************************************************************************
.xaml 내용
<Window x:Class="IValueConverterDemo.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:Me="clr-namespace:IValueConverterDemo"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>
    
        <ResourceDictionary>             
            <Me:IntToBoolenValueConverter x:Key="intToBoolenValueConverter" ></Me:IntToBoolenValueConverter>
            <DataTemplate x:Key="ListBoxItemTemplate" >
                <StackPanel Orientation="Horizontal">
                    <CheckBox IsChecked="{Binding Path=dtChecked, Converter={StaticResource intToBoolenValueConverter}}"></CheckBox>
                    <TextBlock Text="{Binding Path=dtText}"></TextBlock>                   
                </StackPanel>
            </DataTemplate>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <ListBox Name="LstBox" ItemsSource="{Binding}" ItemTemplate="{StaticResource ListBoxItemTemplate}" ></ListBox>
    </Grid>
</Window>

.cs 내용

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Data;

namespace IValueConverterDemo
{
    /// <summary>
    /// Window1.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            DataTable dt = new DataTable();
            dt.Columns.Add("dtChecked");
            dt.Columns.Add("dtText");

            dt.Rows.Add( 1, "0 to False , 1 to True");
          dt.Rows.Add( 0, "0 to False , 1 to True");

            LstBox.DataContext = dt;
        }
    }

    [ValueConversion( typeof(int), typeof(bool))]
    public class IntToBoolenValueConverter : IValueConverter
    {
        #region IValueConverter 멤버
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            int i = System.Convert.ToInt32(value);
            return i != 0;
        }
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            bool b = System.Convert.ToBoolean(value);
            return b ? 1 : 0;
        }
        #endregion
    }

}



Ms-SQL의 sys.Objects 같은 내부 뷰 등으로 간단한 사용툴들을 만들었는데

오라클은 아래 링크에서 확인 가능함.


http://blog.naver.com/kmymk?Redirect=Log&logNo=110082928906