WPF 에서 기본 폰트를 설정해 놓고 아래와 같이 상속받아 사용하는 방법입니다.

이렇게 스타일을 지정해 놓으면 일괄적으로 폰트변경 등등이 쉽게 가능합니다.

Control 에다가 스타일을 설정합니다
    <Style TargetType="{x:Type Control}" x:Key="baseStyle">
            <Setter Property="FontSize" Value="11" />
            <Setter Property="FontFamily" Value="Arial Narrow,Malgun Gothic" />
        </Style>
 
Style.BasedOn 을 설정해서 서브스타일에 BasedOn 적용을한다.
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource baseStyle}"></Style>
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource baseStyle}"></Style>
<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource baseStyle}"></Style>
<Style TargetType="{x:Type ListView}" BasedOn="{StaticResource baseStyle}"></Style>
 

image

image

참고 URL

http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=KO-KR&k=k(SYSTEM.WINDOWS.STYLE.BASEDON);k(VS.XAMLEDITOR);k(TargetFrameworkMoniker-%22.NETFRAMEWORK%2cVERSION%3dV3.5%22)&rd=true

 

데이터템플릿 안의 유저컨트롤에 걍 값을 바인딩하면 오류가 난다.

        
	public string UserName { set; get; }//오류발생
        public UserControl1()
        {
            InitializeComponent();
            //UserName 값을 받아서 유저컨트롤에서 특정행위를 하고싶다.
        }

image

 

이때는 DependencyProperty 등록을 해주면된다.

 

사용되는 데이터

    public class Person
    {
        public int Age { set; get; }
        public string Name { set; get; }
    }

메인창

아래보면 llistboxPerson 리스트박스에 DataTemplate1 으로 나타내고있다.

DataTemplate1 안에는 또 UserControl1이 있으며 UserName="{Binding Name}" 값을 바인딩하고 있다.

<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" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" xmlns:local="clr-namespace:테스트용" mc:Ignorable="d" x:Class="테스트용.MainWindow"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <DataTemplate x:Key="DataTemplate1">
            <Grid Height="85" Width="252">
                <local:UserControl1 HorizontalAlignment="Stretch" Height="Auto" Margin="0,2,0,0" VerticalAlignment="Stretch" Width="Auto" UserName="{Binding Name}"/>                
            </Grid>
        </DataTemplate>
    </Window.Resources>
    <Grid >
        <Grid.Background>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="#FF686868" Offset="0"/>
                <GradientStop Color="#FF606060" Offset="1"/>
            </LinearGradientBrush>
        </Grid.Background>        
        <Grid.RowDefinitions>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <ListBox Margin="12,12,0,118" ItemTemplate="{DynamicResource DataTemplate1}" Name="llistboxPerson" HorizontalAlignment="Left" Width="479" />
    </Grid>
</Window>

데이터템플릿

유저컨트롤의 UserName="{Binding Name}" 이런씩으로 값을 바인딩하고 있다.

    <Window.Resources>
        <DataTemplate x:Key="DataTemplate1">
            <Grid Height="85" Width="252">
                <local:UserControl1 HorizontalAlignment="Stretch" Height="Auto" Margin="0,2,0,0" VerticalAlignment="Stretch" Width="Auto" UserName="{Binding Name}"/>                
            </Grid>
        </DataTemplate>
    </Window.Resources>

 

유저컨트롤

.xaml

    <Grid>
        <TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="데이터템플릿의 바인딩값을 유저컨트롤에 넘겨주기" VerticalAlignment="Top" Background="#FF8F8F8F" Width="296" />
        <Label Content="{Binding Path=Name}" Height="36" HorizontalAlignment="Left" Margin="127,22,0,0" Name="label1" VerticalAlignment="Top" Width="157" />
        <Label Content="유저컨트롤바인딩값:" Height="36" HorizontalAlignment="Left" Margin="5,22,0,0" Name="label2" VerticalAlignment="Top" Width="124" />
    </Grid>

.cs

    /// <summary>
    /// UserControl1.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class UserControl1 : UserControl
    {

        /// <summary>
        /// The dependency property of the ProgressReporter UserControl to display in the GUI
        /// </summary>
        public static DependencyProperty PercentProperty = DependencyProperty.Register("UserName", typeof(string), typeof(UserControl1));
        /// <summary>
        /// The PercentToShow value
        /// </summary>
        public string UserName
        {
            get
            {
                return (string)GetValue(PercentProperty);
            }
            set
            {
                SetValue(PercentProperty, value);
            }
        }

        public UserControl1()
        {
            InitializeComponent();            
        }
    }

추가정보

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

 

image

 

숫자 바인딩 된 값을 금액형식으로 표시하기

Amount 는 숫자타입(int , flot 등등)이여야 합니다.

<TextBlock TextWrapping="Wrap" Text="{Binding Amount, StringFormat=\{0:N0\}}" TextAlignment="Right"/>

 

비하인드 코드에서 바인딩으로 금액표시 만들기

 

   /// 
    /// MainWindow.xaml에 대한 상호 작용 논리
    /// 
    public partial class MainWindow : Window
    {


        public int Amount { set; get; }
        Binding myBinding = new Binding("Amount");    

        public MainWindow()
        {
            InitializeComponent();


                
            myBinding.Source = this;
            myBinding.StringFormat = "{0:N0}";
            myBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; //즉시업데이트
            //텍스트박스의 텍스트에 바인딩을 설정하겠다.
            this.textBox1.SetBinding(TextBox.TextProperty, myBinding); //
           
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
           //myBinding.UpdateSourceTrigger 를  UpdateSourceTrigger.Explicit; 로 설정했을때 명시적으로 업데이트 시키기
            BindingExpression be = this.textBox1.GetBindingExpression(TextBox.TextProperty);
            be.UpdateSource();

        }
    }
 

 

image

 

 

딱 봐도 추천할만한 방법은 아니다. ! ㅋ

저렇게 하면 된다는정도만 알고 응용하시길… ㅜ_ㅜ

기본적으로 하나의 행에 하나의 바인딩 밖에 안되므로;;;;
ConverterParameter 에 바인딩값을 넘길수가 없습니다.
그래서 멀티바인딩으로 값을 두개 가지고 IMultiValueConverter 에서 처리합니다.
<UserControl.Resources>
        <Com_ControlLibrary_Convert:SchoolConvertMultiBinding x:Key="SchoolConvertMultiBinding"/>

        <DataTemplate x:Key="SchoolNameDataTemplate">
            <Grid>
                <TextBlock HorizontalAlignment="Left" TextWrapping="Wrap"  >
                    <TextBlock.Text>
                     <MultiBinding Converter="{StaticResource SchoolConvertMultiBinding}">
                    <Binding Path="SchoolCode" /> 학교코드와 학교이름을 같이 넘긴다. 학교코드가 없으면 학교이름을 리턴
                    <Binding Path="SchoolName" />
                    </MultiBinding>
                  </TextBlock.Text>

                </TextBlock>
            </Grid>
        </DataTemplate>
    
    </UserControl.Resources>

SchoolConvertMultiBinding

class RemainingTimeConverter : IMultiValueConverter
    {
        #region IMultiValueConverter Members
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            //values[0] is SchoolCode
            //values[1] is SchoolName
            throw new NotImplementedException();
        }
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {

                  string[] splitValues = ((string)value).Split(' ');
                  return splitValues;

        }
        #endregion
    }

WPF 에서 다국어 지원하는 방법이 여러가지 있습니다.

MS 에서는 LocBaml 툴을 사용해서 다국어 지원을 권장(?) 하고 있습니다.

http://msdn.microsoft.com/ko-kr/library/ms746621(v=vs.90).aspx

근데 이것은 프로그램이 개발이 완료 되고 나서 했을 때 가장 빠르고 편하며 아래와 같이 엑셀파일도 만들어 주어서 입력하기도 편합니다.

image

 

배포를 하면 아래와 같이 개개의 언어별로 생성이 됩니다.

imageimage

참고 아래와 같이 msbuild 를 이용해서 컨트롤의 UID를 만드는데

*msbuild /t:updateuid helloapp.csproj

프로젝트 위치에 ex)d:\Visual Studio2010\wpfAppliction1 <--- 공백등이 있으면 오류가 발생합니다.

image

 

공백없이 잘 실행된 예

image

 

컨텐츠내용이 변경되면 다시 파일을 만들어야함!!!

암튼 저는 개발 중이라 반수동(?)으로 다국어 지원을 아래와 같이 하기로 맘먹음 ㅋ

다국어 지원하기

프로젝트 구성

image

 

image

 

다국어 파일만들기

영어

image

image

한국어

image

image

App.xaml 에서 만들어진 다국어 리소스를 등록합니다.

image

 

디자인모드에서 다국어 리소스 반영하기

image

( 다국어 내용이 많아지면 안습 이겠따 ㅡ_ㅡ )

소스코드

아래코드는 특별한것은 없습니다.

  string requestedCulture = string.Format("StringResources.{0}.xaml", culture); 리소스 파일을 찾아서

그 리소스를 기본으로 사용합니다.

 

    /// <summary>
    /// MainWindow.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            //SelectCulture("ko-KR");
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
           
            SelectCulture("ko-KR");
            ViewCultInfo();
        }



        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            SelectCulture("en-US");
            ViewCultInfo();
        }

        private void ViewCultInfo()
        {
            this.textBlock4.Text = CultureInfo.CurrentCulture.DisplayName;
            this.textBlock1.Text = FindResource("HelloText").ToString();
        }


        public static void SelectCulture(string culture)
        {
            // List all our resources       
            List<ResourceDictionary> dictionaryList = new List<ResourceDictionary>();
            foreach (ResourceDictionary dictionary in Application.Current.Resources.MergedDictionaries)
            {
                dictionaryList.Add(dictionary);
            }
            // We want our specific culture       
            string requestedCulture = string.Format("StringResources.{0}.xaml", culture);
            ResourceDictionary resourceDictionary = dictionaryList.FirstOrDefault(d => d.Source.OriginalString == requestedCulture);
            if (resourceDictionary == null)
            {
                //리소스를 찾을수 없다면 기본 리소스로 지정      
                requestedCulture = "StringResources.ko-KR.xaml";
                resourceDictionary = dictionaryList.FirstOrDefault(d => d.Source.OriginalString == requestedCulture);
            }
             if (resourceDictionary != null)
             {
                Application.Current.Resources.MergedDictionaries.Remove(resourceDictionary);
                Application.Current.Resources.MergedDictionaries.Add(resourceDictionary);
            }

            //지역화 설정
            Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(culture);
            Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);
        }

    }

 

실행된 모습

image

image

WPF 툴킷을 이용하면 자동완성을 구현 할 수 있다.

근데 이게 중간단어 검색도 안되고 좀 불편해서 지랄맞다 ㅜ_ㅜ

http://kojaedoo.tistory.com/607

 

 

 

 

그래서  걍 만드는게 속편함

일단 허접하게 만들어서 사용하자

(항상 얘기하지만 이 코드는 최적화가 안되었슴다.)

 

우선 UI 부터 보고 얘기

 

중간단어 검색도 사용가능! 키보드로 위아래 이동가능!

개체도 받아올수 있다!

물론 개체이름이 중복이 아닐때 ㅜㅜ

아래는 개체를 통해서 9살이라는 걸 받아옴

코드시작

바인딩되는 Person.cs 개체

이코드를 자동완성 아이템  소스로 사용할꺼다

WindowAutoComplate.xaml UI

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfRibbonApplication1" xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero" 
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
        mc:Ignorable="d" x:Class="WpfRibbonApplication1.WindowAutoComplate"
        Title="WindowAutoComplate" 
        Height="339" Width="575" 
        xmlns:my1="http://schemas.microsoft.com/winfx/2006/xaml/presentation/ribbon">
    
    <Window.Resources>    
    </Window.Resources>
    <Grid>
        <Grid.Background>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="#FFB2B2B2" Offset="0"/>
                <GradientStop Color="#FF5C5C5C" Offset="1"/>
            </LinearGradientBrush>
        </Grid.Background>
        <local:CustomAutoComplateBox Margin="51,95,208,172" x:Name="CustomAuto" Text="" />
        <Label Content="자동완성" Height="28" HorizontalAlignment="Left" Margin="51,61,0,0" Name="label1" VerticalAlignment="Top" Foreground="White" />
        <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="270,134,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
        <TextBlock Height="23" HorizontalAlignment="Left" Margin="51,134,0,0" Name="textBlock1" Text="TextBlock" VerticalAlignment="Top" Width="133" />
    </Grid>
</Window>

 

 

WindowAutoComplate.xaml.cs

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

            List<Person> list = new List<Person>();

            //데이터바인딩할 개체
            for (int i = 0; i < 10; i++)
            {
                list.Add(new Person() { Name = "kojaedoo" + i.ToString(), Age = i });
            }
            for (int i = 0; i < 10; i++)
            {
                list.Add(new Person() { Name = "고재두" + i.ToString(), Age = i });
            }            

            //리스트박스에 표시될 이름
            this.CustomAuto.DisplayMemberPath = "Name";
            this.CustomAuto.DataSource = list;            
        }


        private void button1_Click(object sender, RoutedEventArgs e)
        {
            if( this.CustomAuto.SelectedItem != null){
                this.textBlock1.Text = "이사람의 나이는"+((Person)this.CustomAuto.SelectedItem).Age.ToString();
            }
        }
    }

 

 

CustomAutoComplateBox.CS 소스코드

아래에 보면 AutoComplateBindingData 클래스가 하나 더 있습니다. 여기서 어떤객체가 들어올지 모르기 때문에 여기서

이렇게 담아두고 DisplayMemberPath 넘겨줘서 ToString 할때 DisplayMemberPath  이름의 프로퍼티를 찾습니다.

 

아래는 외부에서 바인딩 할때 사용법입니다. 그럼 자동완성에는 Name이 표시된다.. Age를입력하면 리스트박스에 Age가 출력되며 Age 자동완성이 돌아간다.

 

 

여기서 부터 코드 시작

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Collections;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
using System.Reflection;
using System.Windows.Input;
namespace WpfRibbonApplication1
{

    public class CustomAutoComplateBox : Grid
    {
        private Popup __Popup = new Popup();
        private ListBox __ListBox = new ListBox();
        private TextBox __TextBox = new TextBox();

        /// <summary>
        /// 셀렉트박스에서 사용자가 선택하고 있는 상태를 관리한다.
        /// </summary>
        private bool __IsUserSelected = false;

        private List<AutoComplateBindingData> __AutoComplateBindingDataSourceList = new List<AutoComplateBindingData>();
        public CustomAutoComplateBox()
        {
            __TextBox.Text = "자동완성 텍스트 박스";

            __Popup.Name = "AutoPop";
            //_ListBox.Background = Brushes.Red;
            __ListBox.BorderBrush = Brushes.Orange;
            __ListBox.Background = Brushes.Orange;
            __ListBox.Foreground = Brushes.White;

            __Popup.Child = __ListBox;

            this.Children.Add(__TextBox);
            this.Children.Add(__Popup);

            __TextBox.TextChanged += new TextChangedEventHandler(tb_TextChanged);
            __TextBox.LostFocus += new RoutedEventHandler(tb_LostFocus);

            __TextBox.PreviewKeyUp += new System.Windows.Input.KeyEventHandler(__TextBox_PreviewKeyUp);
            __ListBox.SelectionChanged += new SelectionChangedEventHandler(__ListBox_SelectionChanged);
           

        }



        void __TextBox_PreviewKeyUp(object sender, System.Windows.Input.KeyEventArgs e)
        {
            var uie = e.OriginalSource as UIElement;

            if (e.Key == Key.Down)
            {
                e.Handled = true;

                MoveToListCursor(1);
            }

            if (e.Key == Key.Up)
            {
                e.Handled = true;
                MoveToListCursor(-1);
            }

            if (e.Key == Key.Enter)
            {
                e.Handled = true;
                if (this.__ListBox.SelectedItem != null)
                {
                    this.__TextBox.Text = this.__ListBox.SelectedItem.ToString();
                    this.__TextBox.Select(__TextBox.Text.Length, 0);

                }
                CloseListBox();
            }
        }


        /// <summary>
        /// 테스트박스에서 사용자가 한칸내림 한칸올림 사용할수 있게 처리
        /// </summary>
        /// <param name="p"></param>
        private void MoveToListCursor(int p)
        {
            int moveIndex = this.__ListBox.SelectedIndex + p;

            if (moveIndex <= -1 || this.__ListBox.Items.Count <= 0) //행이없음 내려가거나 올라갈 이유가 없음
            {
                if (this.__Popup.IsOpen)
                {
                    __IsUserSelected = false;
                    CloseListBox();
                    return;
                }
            }
            if (moveIndex > -1 && moveIndex <= this.__ListBox.Items.Count)
            {
                __IsUserSelected = true;
                this.__ListBox.SelectedIndex = moveIndex;
                OpenListBox();
            }

        }

        void __ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (((ListBox)sender).SelectedItem != null)
            {
                string result = ((ListBox)sender).SelectedItem.ToString();
                if (__IsUserSelected == false)
                {
                    this.__TextBox.Text = result;
                    this.__TextBox.Select(__TextBox.Text.Length, 0);
                }
            }
        }

        void tb_LostFocus(object sender, RoutedEventArgs e)
        {
            e.Handled = true;
            CloseListBox();
        }

        void tb_TextChanged(object sender, TextChangedEventArgs e)
        {
            e.Handled = true;
            FindText();
        }

        private void FindText()
        {
            this.__ListBox.ItemsSource = null;
            if (!string.IsNullOrWhiteSpace(this.__TextBox.Text))
            {
                var query = from c in __AutoComplateBindingDataSourceList
                            where c.ToString().Contains(this.__TextBox.Text)
                            select c;
                this.__ListBox.ItemsSource = query;

                OpenListBox();
            }
            else
            {
                CloseListBox();
            }

        }

        private void OpenListBox()
        {
            this.__Popup.Visibility = System.Windows.Visibility.Visible;
            if (this.__ListBox.Items.Count <= 0)
            {
                this.__ListBox.Visibility = System.Windows.Visibility.Collapsed;
            }
            else
            {
                this.__ListBox.Visibility = System.Windows.Visibility.Visible;
            }

            this.__Popup.IsOpen = true;
        }

        private void CloseListBox()
        {
            if (this.__ListBox.Items.Count > 0)
            {
                this.__ListBox.SelectedIndex = -1;
            }
            this.__Popup.Visibility = System.Windows.Visibility.Collapsed;
            this.__Popup.IsOpen = false;
        }

        private IEnumerable _DataSource;
        /// <summary>
        /// 자동완성에서 검색할 데이터소스
        /// </summary>
        public IEnumerable DataSource
        {
            get { return _DataSource; }
            set
            {
                _DataSource = value;
                __BindListBox(value);
            }

        }

        private void __BindListBox(IEnumerable values)
        {
            foreach (var value in values)
            {
                this.__AutoComplateBindingDataSourceList.Add(new AutoComplateBindingData(value as Object, DisplayMemberPath));
            }
        }

        private string _DisplayMemberPath;
        /// <summary>
        /// 바인딩하기 전에 먼저 설정
        /// </summary>
        public string DisplayMemberPath
        {
            get
            {
                return _DisplayMemberPath;
            }
            set
            {
                _DisplayMemberPath = value;
            }
        }

        private object __SelectedItem;

        /// <summary>
        /// 텍스트박스와 동일한 개체 받아오기
        /// </summary>
        public object SelectedItem
        {
            get
            {
                try
                {
                    var query = (from c in __AutoComplateBindingDataSourceList
                                 where c.ToString() == this.__TextBox.Text.Trim()
                                 select c).Single();
                    return ((AutoComplateBindingData)query).ObjectData;
                }
                catch
                {
                    return null;
                }

            }
            set { __SelectedItem = value; }
        }

        /// <summary>
        /// 텍스트박스 텍스트 세팅
        /// </summary>
        public string Text
        {
            get { return this.__TextBox.Text; }
            set { this.__TextBox.Text = value; }
        }
    }

    /// <summary>
    /// 자동완성에 바인딩 될 데이터소스
    /// </summary>
    public class AutoComplateBindingData
    {
        private string __propertyName;
        private Type __type;
        private Object __ObjectData;

        public Object ObjectData
        {
            get { return __ObjectData; }
            set { __ObjectData = value; }
        }

        /// <summary>
        /// 자동완성에 바인딩 될 데이터소스
        /// </summary>
        /// <param name="member">바인딩될 객체</param>
        /// <param name="propertyName">검색 리스트에 표시될 프로퍼티 이름</param>
        public AutoComplateBindingData(Object member, string propertyName)
        {
            if (null == member)
            {
                throw new ArgumentNullException("member");
            }

            if (String.IsNullOrWhiteSpace(propertyName))
            {
                throw new ArgumentNullException("propertyName");
            }

            __type = member.GetType();
            __ObjectData = member;
            __propertyName = propertyName;

        }

        public override string ToString()
        {
            Object value = __type.GetProperty(
                __propertyName,
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).GetValue(__ObjectData, new Object[] { });

            return (value ?? String.Empty).ToString();
        }

    }

}

느낌상 반박자 느린거 같다!?

 

	private void Grid_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter) 
            {
                Debug.WriteLine("Enter");
            }

            if ((Keyboard.GetKeyStates(Key.LeftCtrl) & KeyStates.Down) > 0)
            {
                if (e.Key == Key.S)
                {
                    Debug.WriteLine("Ctrl + S");
                }
            }
           
        }

 

출처MSDN:

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

아래는 자동완성을 테스트할 프로젝트입니다.

image

ViewAppointBaseCode.cs는 자동완성시 나타날 데이터소스다 아래처럼…

 

 

 

ToolKit 다운로드하기

http://kojaedoo.tistory.com/606

http://wpf.codeplex.com/releases/view/40535

로 가서  WPF Toolkit 을 다운로드 합니다.

 

그리고

프로젝트에 참조를 추가

합니다.

툴킷을 설치했다면  C:\Program Files\WPF Toolkit\v3.5.50211.1 밑에 파일이 있습니다.

image

 

 

찾아서 참조해주세요

image

WPFToolkit 없으니깐 빌드할때 오류 ㅋ

 

참고로 추가했어도 VS2010 이여서 그런지 모르겠지만 도구상자에 안나타납니다.

(항목추가해도 마찬기지)

 

빌드한판 하시고

Microsoft Expression Blend 에서 프로젝트를 열어줍니다.

image

 

Blend 에서 검색하면 또 나오네????? 아래와 같이 끌어서 추가

image

이제 비하인드 코드에서 연결만 해주면 됩니다.

Xaml 에서는 요렇게 붙어있습니다.

image

image

 

데이터소스 바인딩

        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            //kojaedoo는 01의 코드값을 가집니다.
            List<ViewAppointBaseCode> _AutoCompleteBoxDataList = new List<ViewAppointBaseCode>();
            _AutoCompleteBoxDataList.Add(new ViewAppointBaseCode() { Code = "01", DisplayName = "kojaedoo" });
            _AutoCompleteBoxDataList.Add(new ViewAppointBaseCode() { Code = "02", DisplayName = "kojaedoo2" });
            _AutoCompleteBoxDataList.Add(new ViewAppointBaseCode() { Code = "03", DisplayName = "kojaedoo3" });
            _AutoCompleteBoxDataList.Add(new ViewAppointBaseCode() { Code = "04", DisplayName = "kojaedoo4" });
            _AutoCompleteBoxDataList.Add(new ViewAppointBaseCode() { Code = "05", DisplayName = "kojaedoo5" });
            //자동완성에 표시될 항목
            NationAutoComplateBox.ValueMemberPath = "DisplayName"; 
            this.NationAutoComplateBox.ItemsSource = _AutoCompleteBoxDataList;
        }

코드값을 확인해보자

        private void button1_Click_1(object sender, RoutedEventArgs e)
        {
            ViewAppointBaseCode vc = this.NationAutoComplateBox.SelectedItem as ViewAppointBaseCode;
            if (vc != null)
            {
                this.label1.Content = vc.Code;
            }
        }

 

 

구현된 모습

image

좀이상하다….

코드값은 잘 가지고 옵니다. ㅋ

image

 

image

리스트에 나오는것은 ToString() 값을 가지고 옵니다.

그래서 변경

 

 

ToString() 이것만 오버라이드 했습니다.

image

public  class ViewAppointBaseCodeConvert : ViewAppointBaseCode
{

 

    public override string ToString()
    {
        return base.DisplayName;
    }
}
바인딩 하는부분도 변경

ViewAppointBaseCode 를 ViewAppointBaseCodeConvert 으로 변경

image

 

WPF Toolkit

출처 : http://wpf.codeplex.com/releases/view/40535

What's new in the WPF Toolkit February 2010 Release?

  • AutoCompleteBox
  • Accordion
  • Rating
  • Bug fixes

Bug fixes for common issues, including:

  • DataGrid - Templating, multiple selection, runtime sorting, etc.
  • Calendar/DatePicker - Styling, default values, focus related issues, etc.
  • VSM - Generated transitions
  • UI Automation - Mostly DataGrid UI automation fixes and a few for Calendar/DatePicker

 

Application WPFToolkit.msi

 

Extended WPF Toolkit

 

출처 : http://wpftoolkit.codeplex.com/

 

What's new since release 1.2.0?

What's in the Extended WPF Toolkit 1.2.0 Release?

 

private void MainContentGrid_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
    
    var uie = e.OriginalSource as UIElement;
    //string n = ((FrameworkElement)e.OriginalSource).Name; //컨트롤 이름

    if (e.Key == Key.Enter)
    {
        e.Handled = true; 
        uie.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
        
    }
}

위와 같이 하면MainContentGrid 안에 포함된 (TextBox /ComboBox 등등) 컨트롤이 Tab 순서에 맞게 이동됩니다.

+ Recent posts