image

 

image

WPF 컨트롤을 사용해서 프로그램을 배포했는데 Xp에서 계속오류가 났습니다.

 

하나씩 코드를 지워가면 문제를 해결하는데  결국 ImageSource에 *.Ico 파일이 문제였습니다.

 

<ribbon:Ribbon x:Name="Ribbon" DockPanel.Dock="Top" SelectedIndex="1" ShowQuickAccessToolBarOnTop="True">

              <ribbon:Ribbon.ApplicationMenu>
                    <ribbon:RibbonApplicationMenu >
                        <ribbon:RibbonApplicationMenuItem Header="닫기" ImageSource="/경로/Images/accessibilitycpl.dll_I0145_0409.ico" Name="RibbonApplicationMenuItemClose" Click="RibbonApplicationMenuItemClose_Click" QuickAccessToolBarImageSource="/Com.Mariner.ERP.Insa;component/Images/netshell.dll_I0643_0409.ico">
                        </ribbon:RibbonApplicationMenuItem>
                    </ribbon:RibbonApplicationMenu>
                
                </ribbon:Ribbon.ApplicationMenu>

 

저부분을  *Png 또는 *.GIF *.JPG로 변경 해주세요

아래 화면은 특정 나이를 초과한 사람만  Cell 의 배경을 빨간색으로 표시해서 시각적으로 표현해준다.

 

내용은 아래로 ㄱㄱ

DataGrid

배경색을 IValueConverter 구현해서 특정 조건을 검사한다.

        <DataGrid AutoGenerateColumns="False" HorizontalAlignment="Left" Margin="8,43,0,12" x:Name="dataGrid1" Width="483" SelectionUnit="Cell" >
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name" Binding="{Binding Name}"  Width="100">               
                </DataGridTextColumn>
                <DataGridTextColumn Header="Age" Binding="{Binding Age}"  Width="100">
                    <DataGridTextColumn.CellStyle>
                        <Style TargetType="{x:Type DataGridCell}">
                            <Setter Property="Background">
                                <Setter.Value>
                                    <Binding Converter="{StaticResource BGConvert}"  />
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </DataGridTextColumn.CellStyle>
                </DataGridTextColumn>               
            </DataGrid.Columns>

 

CS Code

namespace UpdateCellWpfApplication
{
    /// <summary>
    /// MainWindow.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class MainWindow : Window
    {
        List<Person> list = new List<Person>();
        public MainWindow()
        {
            InitializeComponent();

            //구라데이터
            list.Add(new Person() { Age = 10, Name = "kojaedoo"});
            list.Add(new Person() { Age = 17, Name = "중딩"});
            list.Add(new Person() { Age = 22, Name = "대딩"});
            list.Add(new Person() { Age = 30, Name = "아저씨"});
            list.Add(new Person() { Age = 20, Name = "kojaedoo"});
            list.Add(new Person() { Age = 3, Name = "유아"});
            list.Add(new Person() { Age = 65, Name = "할아버지"});         
        
            this.dataGrid1.ItemsSource = list;

            StaticManager.SearchValue = 20; //검사할 나이
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
           //검색값이 변경되면 다시 색칠하기 위해서 바인딩을 다시한다 개선되야 할꺼 같따;;;
            StaticManager.SearchValue = int.Parse(this.textBox1.Text);
            this.dataGrid1.ItemsSource = null;
            this.dataGrid1.ItemsSource = this.list;
        }
    }  
}

Person.cs

데이터 바인딩용

public class Person : INotifyPropertyChanged
{
    private string _Name;

    public string Name
    {
        get { return _Name; }
        set
        {
            if (value != this._Name)
            {
                this._Name = value;
                NotifyPropertyChanged("Name");
            }

        }
    }
    private int _Age;

    public int Age
    {
        get
        {
            return _Age;
        }
        set
        {
            if (value != this._Age)
            {
                this._Age = value;
                NotifyPropertyChanged("Age");
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

}

StaticManager .cs
public static class StaticManager
{
    public static int SearchValue { set; get; } //나이를 스태틱으로 컨버터안에서 받기위해
}

BGConvert : IValueConverter

나이를 비교해서 브러쉬 색깔을 지정하고 있다.

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value == null)
        {
            return null;
        }
        Person p = value as Person;
        if (p != null)
        {
            if (p.Age >= StaticManager.SearchValue)
            {
                return Brushes.Red;
            }
            else
            {
                return null;
            }
        }
        else {
            return null;
        }

    }

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

창을 띄우면 새창이 안뜨고 창안에서 좀 간지나게 띄운다. 창안에 뜬 창은 드래그가 가능한다. 코딩한줄 안하고

Blend 에서 Rectangle 을 뒤에 깐다(뒤에 어두운 배경)

앞에 마우스 드래그가 가능하게 Canvas 안에 StackPanel 을 넣어뒀다

 

나는 StackPanel  안에 컨트롤을 바인딩해서 돌려 쓸려고 …..

 

암튼  움직이게 할 컨트롤을 선택한다.

(흰색박스)

도구에서

MouseDragElementBehavior를 선택해서 흰색창에 끌어다 놓는다.

비헤비어가 먹혔다. 이걸로 끗

좀만 손보면 이쁘다

 

헉! 배경창으로 밖으로 나간다.

이럴땐… ConstarinToParntBounds 체크를 해주면 회색배경 안에서만 논다.

 

 

 

팝업창을 가운데 띄우자

팝업창이 뜰때 암때나 뜨지말고 가운데 띄워서 더 이쁘게 ~

설명은 주석으로 끗

   /// <summary>
    /// PopupSelectUI.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class PopupSelectUI : UserControl
    {
        double h;
        double w;
        public PopupSelectUI()
        {
            InitializeComponent();
            Debug.WriteLine(this.IsLoaded);
            this.Loaded += new RoutedEventHandler(PopupSelectUI_Loaded);

        }

        void PopupSelectUI_Loaded(object sender, RoutedEventArgs e)
        {            
            SetCenter();
        }

        /// <summary>
        /// 움직이게 할 컨트롤을 바인딩합니다.
        /// </summary>
        /// <param name="fe"></param>
        public void SetUIContent(FrameworkElement fe) //컨버스 안에 붙는 컨트롤
        {
            h = fe.Height; //컨트롤 가로 세로 높이
            w = fe.Width;
            this.StpDrag.Children.Add(fe);
           
        }

        public void SetCenter()
        {
            this.UpdateLayout();
            double ContentGanvash = this.MainCanvas.ActualHeight; //MainCanvas 는 드래그창을 감싸는 캔버스
            double ContentGanvasw = this.MainCanvas.ActualWidth;

            double winl = (ContentGanvasw - w) / 2;
            double wint = (ContentGanvash - h) / 2;
          
            StpDrag.SetValue(Canvas.TopProperty, wint);
            StpDrag.SetValue(Canvas.LeftProperty, winl);           
        }

        private void StpDrag_MouseMove(object sender, MouseEventArgs e)
        {
            Debug.WriteLine(this.MainCanvas.ActualHeight);
        }

    }

 

참고 URL : http://msdn.microsoft.com/en-us/library/aa969773.aspx

 

별다른건 없고 그냥 Microsoft.Win32 네임스페이스 참조만 해주고 예전처럼 사용하면 됩니다.

image

 

 

Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
dlg.FileName = "Command"; // Default file name
dlg.DefaultExt = ".exe"; // Default file extension
dlg.Filter = "Text documents (.exe)|*.exe"; // Filter files by extension

// Show open file dialog box
Nullable<bool> result = dlg.ShowDialog();

// Process open file dialog box results
if (result == true)
{
    // Open document
    string filename = dlg.FileName;
}

 

WPF 컨트롤의 유효성을 검사할려면 규칙만들고 바인딩 연결(유효성 검사 규칙은 ValidationRule)

image

규칙만들고

using System.Globalization;
using System.Windows.Controls;

namespace SDKSample
{
    public class MarginValidationRule : ValidationRule
    {
        double minMargin;
        double maxMargin;

        public double MinMargin
        {
            get { return this.minMargin; }
            set { this.minMargin = value; }
        }

        public double MaxMargin
        {
            get { return this.maxMargin; }
            set { this.maxMargin = value; }
        }

        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            double margin;

            // Is a number?
            if (!double.TryParse((string)value, out margin))
            {
                return new ValidationResult(false, "Not a number.");
            }

            // Is in range?
            if ((margin < this.minMargin) || (margin > this.maxMargin))
            {
                string msg = string.Format("Margin must be between {0} and {1}.", this.minMargin, this.maxMargin);
                return new ValidationResult(false, msg);
            }

            // Number is valid
            return new ValidationResult(true, null);
        }
    }
}

 

컨트롤에 연결하고

image

using System.Windows; // Window, RoutedEventArgs, IInputElement, DependencyObject
using System.Windows.Controls; // Validation
using System.Windows.Input; // Keyboard

namespace SDKSample
{
    public partial class MarginsDialogBox : Window
    {


...


void okButton_Click(object sender, RoutedEventArgs e)
{
    // Don't accept the dialog box if there is invalid data
    if (!IsValid(this)) return;


...


        }

        // Validate all dependency objects in a window
        bool IsValid(DependencyObject node)
        {
            // Check if dependency object was passed
            if (node != null)
            {
                // Check if dependency object is valid.
                // NOTE: Validation.GetHasError works for controls that have validation rules attached 
                bool isValid = !Validation.GetHasError(node);
                if (!isValid)
                {
                    // If the dependency object is invalid, and it can receive the focus,
                    // set the focus
                    if (node is IInputElement) Keyboard.Focus((IInputElement)node);
                    return false;
                }
            }

            // If this dependency object is valid, check all child dependency objects
            foreach (object subnode in LogicalTreeHelper.GetChildren(node))
            {
                if (subnode is DependencyObject)
                {   
                    // If a child dependency object is invalid, return false immediately,
                    // otherwise keep checking
                    if (IsValid((DependencyObject)subnode) == false) return false;
                }
            }

            // All dependency objects are valid
            return true;
        }
    }
}

 

아 너무 귀찮다 ㅋ 그냥 if( this.text ==””){  } 이런씩으로 올드하게 하면 안되나? ㅎ

실버라이트 초간단 데이터 바인딩

1.ADO.NET Entity Data Model 을 만듭니다 (서버측)

2. 그런다음 데이터베이스에 접근할수 있는 ado.net Data Service 를 만들어줍니다. (서버측)

3.실버라이트 프로젝트에서 웹서비스를 참조합니다.

4.데이터그리드에 데이터를 바인딩 합니다.

5.테스트 끝~

1.ADO.NET Entity Data Model 을 만듭니다

그런다음 데이터베이스테 테이블을 추가시키면 자동으로 만들어 줍니다

BOOK , BookOrderHistory 는 테이블 명입니다

만들어진 ADO.NET Entity Data Model 에 접근한기위한   ado.net Data Service  를 만들어줍니다

using System;

using System.Collections.Generic;

using System.Data.Services;

using System.Linq;

using System.ServiceModel.Web;

using System.Web;

namespace BM.Web

{

public class BookWebDataService : DataService< CITY_GAS_BOOKEntities>

{

// This method is called only once to initialize service-wide policies.

public static void InitializeService(IDataServiceConfiguration config)

{

// TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.

// Examples:

config.SetEntitySetAccessRule("*", EntitySetRights.All);

//config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);

//config.UseVerboseErrors = true;

}

}

}

실버라이트 프로젝트에서 사용하기 위해서 서비스를 참조 시킵니다

BOOK 을 담는  ObservableCollection 클래스를 구현합니다

using System.ComponentModel;
using System.Collections.ObjectModel;
using BM.ServiceReference1;
namespace BM.CodeTest
{
    public class BooksDS : ObservableCollection<BOOK>
    {

        public BooksDS()  : base()
        {
        }

    }
}

실버라이트에서 데이터 그리드 (grdList 로 이름을 주세요 )   를 하나 만들고

CLR Object Data Source 를추가 시켜줍니다. 정상적으로 추가가 되면

BooksDS  찾아서 바인딩 시켜주세요

데이터 그리드에 자동으로 컬럼이 표시됩니다 (자동컬럼으로 설정되었을 경우 )

실제 코드 상의 셀렉트

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
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.Data.Services.Client;
using System.Collections.ObjectModel;
using System.ComponentModel;
using BM.ServiceReference1;
namespace BM.CodeTest
{
    public partial class Delete : UserControl
    {
        ServiceReference1.CITY_GAS_BOOKEntities svcContext;
        ObservableCollection<ServiceReference1.BOOK> ObsvBookCollrection;
        BooksDS bookDs;

        public Delete()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(Delete_Loaded);
        }

        void Delete_Loaded(object sender, RoutedEventArgs e)
        {

            svcContext = new CITY_GAS_BOOKEntities(new Uri("BookWebDataService.svc", UriKind.Relative));
            ObsvBookCollrection = new ObservableCollection<BOOK>();
            bookDs = new BooksDS();
            DataServiceQuery<BOOK> query = (DataServiceQuery<BOOK>)
                (from c in svcContext.BOOK select c);
            query.BeginExecute(GetDataCallback, query);

        }

        #region 셀렉트

        void GetDataCallback(IAsyncResult result)
        {

            try
            {
                DataServiceQuery<BOOK> queryResult =
                               (DataServiceQuery<BOOK>)result.AsyncState;

                IEnumerable<BOOK> results =
                              queryResult.EndExecute(result);

                foreach (var item in results)
                {
                    bookDs.Add(item);
                }
                    grdList.ItemsSource = bookDs;

                MessageBox.Show("도서목록가져오기 완료");

            }
            catch (DataServiceRequestException ex)
            {

            }

        }
        #endregion

    }
}

image

 

보통 컨트롤을 찾을땐 그냥 this.grid1 이렇게 찾는다 하지만

컬렉션안이라든지 DataTemplate 안에서는 찾기가 에메하다 이때는 VisualTreeHelper 를 이용해서찾으면된다.

 

 

        private void button1_Click(object sender, RoutedEventArgs e)
        {

            Button btn = sender as Button;

            //버튼을 기준으로 border1 을 찾고있다.
            Border b = FindVisualParentByName<Border>(btn, "border1");
            b.Background = this.Resources["Brush2"] as Brush;

            //border1 을 기준으로 버튼을 찾고 있다.

            Button FindBtn = FindVisualChildByName<Button>(this.border1, "button2");
            FindBtn.Background = this.Resources["Brush2"] as Brush;
        }


        /// <summary>
        /// 자신의 컨트롤 한단계 위부터 사용자정의 이름으로 검색합니다.
        /// </summary>
        /// <typeparam name="T">결과값의 형식</typeparam>
        /// <param name="_Control">검색을 시작할 컨트롤</param>
        /// <param name="_FindControlName">찾고자하는 컨트롤 이름</param>
        /// <returns></returns>
        private T FindVisualParentByName<T>(FrameworkElement _Control, string _FindControlName) where T : FrameworkElement
        {
            T t = null;
            DependencyObject obj = VisualTreeHelper.GetParent(_Control); //오브젝트검사            

            for (int i = 0; i < 100; i++) //최대 100개의 컨트롤 까지 검색
            {
                string currentName = obj.GetValue(Control.NameProperty) as string;
                if (currentName == _FindControlName)
                {
                    t = obj as T;
                    break;
                }
                obj = VisualTreeHelper.GetParent(obj); //1번  오브젝트 부모니깐 2번오브젝트 불러오기 계속 이런씩으로 검색 
                if (obj == null) //더이상 검사할 컨트롤 없다 빠져 나가자 ㅡ_ㅡ
                {
                    break;
                }
            }

            return t;

        }

        /// <summary>
        /// 자신의 컨트롤 한단계 아래부터 사용자정의 이름으로 검색합니다.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="_Control"></param>
        /// <param name="_FindControlName"></param>
        /// <returns></returns>
        private T FindVisualChildByName<T>(DependencyObject _Control, string _FindControlName) where T : DependencyObject
        {
          
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(_Control); i++)
            {
                var child = VisualTreeHelper.GetChild(_Control, i);
                string controlName = child.GetValue(Control.NameProperty) as string;
                if (controlName == _FindControlName)
                {
                   return child as T;
                }
                else
                {
                    T result = FindVisualChildByName<T>(child, _FindControlName);
                    if (result != null)
                    {
                        return result;
                    }
                }

            }
            return null;
        }

http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=KO-KR&k=k(SYSTEM.WINDOWS.DEPENDENCYOBJECT.GETVALUE);k(TargetFrameworkMoniker-%22.NETFRAMEWORK%2cVERSION%3dV4.0%22);k(DevLang-CSHARP)&rd=true

 

유효 값은 속성 시스템에서 값을 요청하는 호출자에게 반환하는 속성의 값입니다.속성 시스템에서 속성 시스템 값 우선 순위에 참가하는 가능한 모든 입력을 계산하면 유효 값이 생성됩니다.여기에는 강제 형 변환 및 애니메이션이 포함됩니다.자세한 내용은 종속성 속성 값 우선 순위을 참조하십시오.

이 메서드는 UnsetValue를 반환하지 않습니다.UnsetValue는 내부적으로 다양한 기능에 사용되며 강제 형 변환 콜백을 통해 노출되기도 하는 속성 시스템에 대한 센티널 값입니다.

속성의 형식이 확실하지 않는 경우에는 요청된 종속성 속성의 식별자를 쿼리하여 반환 값을 변환할 수 있는 보다 구체적인 PropertyType이 있는지를 확인할 수 있습니다.

 

 

public class MyStateControl : ButtonBase
{
  public MyStateControl() : base() { }
  public Boolean State
  {
    get { return (Boolean)this.GetValue(StateProperty); }
    set { this.SetValue(StateProperty, value); } 
  }
  public static readonly DependencyProperty StateProperty = DependencyProperty.Register(
    "State", typeof(Boolean), typeof(MyStateControl),new PropertyMetadata(false));
}

 

또다른 예제

아래 메소드는 자기위치부터 아래로 컨트롤 찾는 메소드 입니다.

여기서는 string controlName = child.GetValue(Control.NameProperty) as string;

이렇게 컨트롤의 이름을 가지고 오고 있습니다

        /// <summary>
        /// 자신의 컨트롤 한단계 아래부터 사용자정의 이름으로 검색합니다.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="_Control"></param>
        /// <param name="_FindControlName"></param>
        /// <returns></returns>
        private T FindVisualChildByName<T>(Control _Control, string _FindControlName) where T : FrameworkElement
        {
            T t = null;
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(_Control); i++)
            {
                var child = VisualTreeHelper.GetChild(_Control, i);
                string controlName = child.GetValue(Control.NameProperty) as string;
                if (controlName == _FindControlName)
                {
                    t = child as T;
                }
               
            }
            return t;
        }

데이터그리드를 이용해서 바로 편집 할 수 있도록 한다.

데이터그리드에서 바로 보이는 화면을 편집할떄는

프로그램은 이름과 나이를 입력하는데 이름은 콤보박스로 정해져있는사람만 선택가능하게 한다.

나이는 텍스트박스로 입력하게 한다

 

아래에서는 나이 수정 부분은 제외

 

 

적당하게 데이터 그리드를 그려주고

Person 클래스를 바인딩해주자 컬럼은 Name 과 Age를 준다.

바인딩용 클래스

  public class Person : INotifyPropertyChanged
    {
        private string _Name;

        public string Name
        {
            get
            {
                return _Name;
            }
            set
            {
                _Name = value;
                OnPropertyChanged("Name");
            }
        }
        private int _Age;

        public int Age
        {
            get
            {
                return _Age;
            }
            set
            {
                _Age = value;
                OnPropertyChanged("Age");

            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }
    }

 

생성자에서 바인딩하기 (그냥 간단하게 바인딩 했따 귀찮아… ㅋ)

        private void CreatePersonDataList()
        {
            for (int i = 0; i < 10; i++)
            {
                PersonList.Add(new Person() { Name = "kojaedoo" + i.ToString(), Age = 10 + i });
            }

            ControlPersonList = new List<Person>(PersonList);

            this.dataGrid1.ItemsSource = PersonList;

        }

템플릿편집

 

 

CellTemplate 을 선택해서 우선 일반 상태일때 디자인 작업

 

 

{StaticResource NameDataTemplate}

주의!

Blend 에서 템플릿을 만들면 DynamicResource 로 만들어진다. 실제로 테스트해보면 바인딩된 데이터가 표시가 안된다.

이부분을

 

스태틱리소스로 변경해주자

Blend 에서 하면 DynamicResource  비주얼 스튜디오에서 만들면  StaticResource 으로 만들어주네…

 

그다음 위와같은방법으로  CellEditingTemplate 을 만들어서 콤보박스를 넣어준다.

 

에디트화면 진입 화면

 

소스

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="Com.Mariner.ERP.TestWPF.DataGridEdit"
        Title="DataGridEdit" Height="386" Width="671">
    <Window.Resources>
        <!--이름디스플레이-->
        <DataTemplate x:Key="NameDataTemplate">
            <Grid>
                    <TextBlock Text="{Binding Path=Name}" />                    
            </Grid>
        </DataTemplate>
        <!--이름클릭했을때 콤보박스로 보여주기-->
        <DataTemplate x:Key="NameEditTemplate" >

            <ComboBox Margin="0" d:LayoutOverrides="Height"  x:Name="chbName"  SelectedValue="{Binding Name}" />
            
        </DataTemplate>
        <!--나이디스플레이-->
        <DataTemplate x:Key="AgeDataTemplate">
            <Grid>
                <TextBlock Margin="0" TextWrapping="Wrap" Text="{Binding Age}"/>
            </Grid>
        </DataTemplate>
        
    </Window.Resources>
    <Grid>
        <!--PreparingCellForEdit 수정화면들어가기전 이벤트
        CellEditEnding 수정이 끝나고나서 이벤트-->
        <DataGrid AutoGenerateColumns="False" Margin="8,140,8,8" x:Name="dataGrid1" PreparingCellForEdit="dataGrid1_PreparingCellForEdit" CellEditEnding="dataGrid1_CellEditEnding">
            <DataGrid.Columns>
                <DataGridTemplateColumn  Header="Name" CellTemplate="{StaticResource NameDataTemplate}" CellEditingTemplate="{StaticResource NameEditTemplate}"  />
                <DataGridTemplateColumn Header="Age" CellTemplate="{DynamicResource AgeDataTemplate}"/>                
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

 

비하인드코드

        private void dataGrid1_PreparingCellForEdit(object sender, DataGridPreparingCellForEditEventArgs e)
        {
            string s = e.Column.Header.ToString();

            switch (s.ToLower())
            {
                case "name": //이름클릭했다면
                    ComboBox chb = VisualTreeHelper.GetChild(e.EditingElement, 0) as ComboBox; //콤보박스찾아주기
                    chb.DisplayMemberPath = "Name";
                    chb.SelectedValuePath = "Name";

                    if (chb.Items.Count <= 0) //콤보박스 데이터바인딩
                    {
                        foreach (var item in ControlPersonList)
                        {
                            chb.Items.Add(item);
                        }
                    }

                    break;

                default:
                    break;
            }
        }

        private void dataGrid1_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
        {
            //수정완료검사
            ComboBox chb = VisualTreeHelper.GetChild(e.EditingElement, 0) as ComboBox;
            Person ps = chb.SelectedItem as Person;
            if (ps == null) //콤보박스 값이 없다면 수정을 취소로 돌려주자
            {
                e.Cancel = true;
                
            }
        
       }

 

TwoWay

실제 데이터와 컨트롤에서 변경된 값을 적용할려면  Mode를 양방향으로 설정해야합니다.

참고 URL

http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=KO-KR&k=k(SYSTEM.WINDOWS.DATA.BINDING.MODE)%3bk(VS.XAMLEDITOR)%3bk(TargetFrameworkMoniker-%22.NETFRAMEWORK%2cVERSION%3dV4.0%22)&rd=true

  • TwoWay updates the target property or the property whenever either the target property or the source property changes.

  • OneWay updates the target property only when the source property changes.

  • OneTime updates the target property only when the application starts or when the DataContext undergoes a change.

  • OneWayToSource updates the source property when the target property changes.

  • Default causes the default Mode value of target property to be used.

  • StaticResource는 이미 정의된 리소스의 값을 대체하여 XAML 속성의 값을 제공합니다.StaticResource 평가는 궁극적으로 XAML 로드 시간에 수행되고 실제 런타임에는 개체 그래프에 액세스하지 못합니다. 자세한 내용은 StaticResource 태그 확장을 참조하십시오.

    image

  • DynamicResource는 값이 리소스에 대한 런타임 참조가 되도록 지연하여 XAML 속성의 값을 제공합니다.동적 리소스 참조는 리소스가 액세스될 때마다 새로 조회하도록 하고 런타임에 개체 그래프에 액세스합니다.이 액세스를 얻기 위해 속성 시스템의 종속성 속성 및 계산된 식에 의해 DynamicResource 개념이 지원됩니다.따라서 WPF에서 사용 가능한 모든 속성에 대해 DynamicResource를 사용할 수 없습니다.자세한 내용은 DynamicResource 태그 확장을 참조하십시오.

  •  

    image

    image 

    날짜데이터를 바인딩하면 위에처럼 시간까지 다 표시된다.

    깔끔하게

    아래와 같이 표시하고 싶다면 StringFormat를 이용하면 끗~

    image

     

    변경방법

    image

    UI에서는

    image

    셀바인딩 선택

    image

    옵션선택

    image

    문자열 서식에 자기가 원하는 스탈로 할수 있다 아래와 같이 기본적으로 자주쓰는 항목은 들어가있다.

     

    image

    + Recent posts