반응형

찰스 페졸드의 WPF 를 읽으면서 정리한 인쇄(PrintaBunchaButtons) 소스.

UIElement에서 파생된 클래스 인스턴스를 인쇄할 때 중요한 단계가 필요하며, 엘리먼트를 배치하기 위해 객체의 Measure와 Arrange 메소드를 호출해야 한다.

Arrange 메소드 호출 후에 UIElement의 InvalidateArrange 메서드를 호출해야 인쇄 시 정상적으로 표시가 된다.

 

[PrintaBunchaButtons.cs 파일]

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace PrintaBunchaButtons
{
    public class PrintaBunchaButtons : Window
    {
        [STAThread]
        public static void Main()
        {
            Application app = new Application();
            app.Run(new PrintaBunchaButtons());
        }

        public PrintaBunchaButtons()
        {
            Title = "Print a Bunch of Buttons";
            SizeToContent = SizeToContent.WidthAndHeight;
            ResizeMode = ResizeMode.CanMinimize;

            //Print 버튼 생성
            Button btn = new Button();
            btn.FontSize = 24;
            btn.Content = "Print ...";
            btn.Padding = new Thickness(12);
            btn.Margin = new Thickness(96);
            btn.Click += PrintOnClick;
            Content = btn;
        }

        private void PrintOnClick(object sender, RoutedEventArgs e)
        {
            PrintDialog dlg = new PrintDialog();

            if ((bool)dlg.ShowDialog().GetValueOrDefault())
            {
                //그리드 패널 생성
                Grid grid = new Grid();

                //자동으로 크기가 변하는 열과 행을 5개 정의
                for (int i = 0; i < 5; i++)
                {
                    ColumnDefinition colDef = new ColumnDefinition();
                    colDef.Width = GridLength.Auto;
                    grid.ColumnDefinitions.Add(colDef);

                    RowDefinition rowDef = new RowDefinition();
                    rowDef.Height = GridLength.Auto;
                    grid.RowDefinitions.Add(rowDef);
                }

                //그라디언트 브러시로 그리드의 배경색을 지정
                grid.Background = new LinearGradientBrush(Colors.Gray, Colors.White, 
                                                          new Point(0, 0), new Point(1, 1));

                //난수 생성
                Random rand = new Random();

                //25개 버튼으로 Grid를 채움
                for (int i = 0; i < 25; i++)
                {
                    Button btn = new Button();
                    btn.FontSize = 12 + rand.Next(8);
                    btn.Content = "Button No. " + (i + 1);
                    btn.HorizontalAlignment = HorizontalAlignment.Center;
                    btn.VerticalAlignment = VerticalAlignment.Center;
                    btn.Margin = new Thickness(6);
                    grid.Children.Add(btn);
                    Grid.SetRow(btn, i % 5);
                    Grid.SetColumn(btn, i / 5);
                }

                //그리드 크기 결정
                grid.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));

                Size sizeGrid = grid.DesiredSize;

                //페이지상의 그리드의 중앙점을 결정
                Point ptGrid = new Point((dlg.PrintableAreaWidth - sizeGrid.Width) / 2,
                                         (dlg.PrintableAreaHeight - sizeGrid.Height) / 2);

                //레이아웃은 설정하지 않고 통과
                grid.Arrange(new Rect(ptGrid, sizeGrid));
                grid.InvalidateArrange();
                //인쇄
                dlg.PrintVisual(grid, Title);
            }
        }
    }
}
반응형
반응형

찰스 페졸드의 WPF 를 읽으면서 정리한 인쇄(PrintWithMargins) 소스.

2개의 클래스 파일을 작성했으며, PrintWithMargins.cs 와 PageMarginsDialog.cs 파일로 구성된다.

 

[PrintWithMargins.cs 파일]

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;

namespace PrintWithMargins
{
    public class PageMarginsDialog : Window
    {
        //종이 테두리를 참조하는 내부 열거형
        enum Side
        {
            Left, Right, Top, Bottom
        }

        //숫자 입력을 위한 텍스트 박스 4개
        TextBox[] txtBox = new TextBox[4];
        Button btnOk;

        //페이지 여백을 위한 타입 Thickness의 Public 프로퍼티
        public Thickness PageMargins
        {
            set
            {
                txtBox[(int)Side.Left].Text = (value.Left / 96).ToString("F3");
                txtBox[(int)Side.Right].Text = (value.Right / 96).ToString("F3");
                txtBox[(int)Side.Top].Text = (value.Top / 96).ToString("F3");
                txtBox[(int)Side.Bottom].Text = (value.Bottom / 96).ToString("F3");
            }
            get
            {
                return new Thickness(Double.Parse(txtBox[(int) Side.Left].Text) * 96,
                                    Double.Parse(txtBox[(int)Side.Right].Text) * 96,
                                    Double.Parse(txtBox[(int)Side.Top].Text) * 96,
                                    Double.Parse(txtBox[(int)Side.Bottom].Text) * 96);
            }
        }

        //생성자
        public PageMarginsDialog()
        {
            //대화상자를 위한 표준 설정
            Title = "Page Setup";
            ShowInTaskbar = false;
            WindowStyle = WindowStyle.ToolWindow;
            WindowStartupLocation = WindowStartupLocation.CenterOwner;
            SizeToContent = SizeToContent.WidthAndHeight;
            ResizeMode = ResizeMode.NoResize;

            //윈도우 Content를 위한 스택 패널을 만든다.
            StackPanel stack = new StackPanel();
            Content = stack;

            //스택 패널의 자식으로 그룹 박스를 생성
            GroupBox grpBox = new GroupBox();
            grpBox.Header = "Margins (inches)";
            grpBox.Margin = new Thickness(12);
            stack.Children.Add(grpBox);

            //그룹 박스의 내용으로 그리드를 생성
            Grid grid = new Grid();
            grid.Margin = new Thickness(6);
            grpBox.Content = grid;

            //2개의 행과 4개의 열
            for (int i = 0; i < 2; i++)
            {
                RowDefinition rowDef = new RowDefinition();
                rowDef.Height = GridLength.Auto;
                grid.RowDefinitions.Add(rowDef);
            }

            for (int i = 0; i < 4; i++)
            {
                ColumnDefinition colDef = new ColumnDefinition();
                colDef.Width = GridLength.Auto;
                grid.ColumnDefinitions.Add(colDef);
            }

            //그리드에 레이블과 텍스트 박스 컨트롤을 추가
            for (int i = 0; i < 4; i++)
            {
                Label lbl = new Label();
                lbl.Content = "_" + Enum.GetName(typeof(Side), i) + ":";
                lbl.Margin = new Thickness(6);
                lbl.VerticalAlignment = VerticalAlignment.Center;
                grid.Children.Add(lbl);
                Grid.SetRow(lbl, i / 2);
                Grid.SetColumn(lbl, 2 * (i % 2));

                txtBox[i] = new TextBox();
                txtBox[i].TextChanged += TextBoxOnTextChanged;
                txtBox[i].MinWidth = 48;
                txtBox[i].Margin = new Thickness(6);
                grid.Children.Add(txtBox[i]);
                Grid.SetRow(txtBox[i], i / 2);
                Grid.SetColumn(txtBox[i], 2 * (i % 2) + 1);
            }

            //OK와 Cancel 버튼을 위해 UniformGrid를 이용
            UniformGrid uniGrid = new UniformGrid();
            uniGrid.Rows = 1;
            uniGrid.Columns = 2;
            stack.Children.Add(uniGrid);

            btnOk = new Button();
            btnOk.Content = "OK";
            btnOk.IsDefault = true;
            btnOk.IsEnabled = false;
            btnOk.MinWidth = 60;
            btnOk.Margin = new Thickness(12);
            btnOk.HorizontalAlignment = HorizontalAlignment.Center;
            btnOk.Click += OkButtonOnClick;
            uniGrid.Children.Add(btnOk);

            Button btnCancel = new Button();
            btnCancel.Content = "Cancel";
            btnCancel.IsCancel = true;
            btnCancel.MinWidth = 60;
            btnCancel.Margin = new Thickness(12);
            btnCancel.HorizontalAlignment = HorizontalAlignment.Center;
            uniGrid.Children.Add(btnCancel);
        }
        /// <summary>
        /// OK를 클릭하면 대화상자를 종료함
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OkButtonOnClick(object sender, RoutedEventArgs e)
        {
            DialogResult = true;
        }
        /// <summary>
        /// 텍스트 박스의 값이 숫자이면 OK 버튼을 활성화
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TextBoxOnTextChanged(object sender, TextChangedEventArgs e)
        {
            double result;

            btnOk.IsEnabled = Double.TryParse(txtBox[(int)Side.Left].Text, out result) &&
                            Double.TryParse(txtBox[(int)Side.Right].Text, out result) &&
                            Double.TryParse(txtBox[(int)Side.Top].Text, out result) &&
                            Double.TryParse(txtBox[(int)Side.Bottom].Text, out result);
        }
    }
}

 

 

[PageMarginsDialog.cs 파일]

using System;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Printing;

namespace PrintWithMargins
{
    public class PrintWithMargins : Window
    {
        //PringDialog의 정보를 저장하기 위한 Private 필드
        PrintQueue prnQueue;
        PrintTicket prnTkt;
        Thickness marginPage = new Thickness(96);

        [STAThread]
        public static void Main()
        {
            Application app = new Application();
            app.Run(new PrintWithMargins());
        }

        public PrintWithMargins()
        {
            Title = "Print with Margins";
            FontSize = 24;

            //윈도우 Content를 위한 스택 패널 생성
            StackPanel stack = new StackPanel();
            Content = stack;

            //페이지 설정 버튼 생성
            Button btn = new Button();
            btn.Content = "Page Set_up...";
            btn.HorizontalAlignment = HorizontalAlignment.Center;
            btn.Margin = new Thickness(24);
            btn.Click += SetupOnClick;
            stack.Children.Add(btn);

            //인쇄 버튼 생성
            btn = new Button();
            btn.Content = "_Print...";
            btn.HorizontalAlignment = HorizontalAlignment.Center;
            btn.Margin = new Thickness(24);
            btn.Click += PrintOnClick;
            stack.Children.Add(btn);
        }
        /// <summary>
        /// 인쇄 버튼 : PringDialog 실행
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PrintOnClick(object sender, RoutedEventArgs e)
        {
            PrintDialog dlg = new PrintDialog();

            //PrintQueue와 PrintTicket 설정
            if (prnQueue != null) dlg.PrintQueue = prnQueue;

            if (prnTkt != null) dlg.PrintTicket = prnTkt;

            if (dlg.ShowDialog().GetValueOrDefault())
            {
                //PrintQueue와 PrintTicket을 대화상자의 값으로 설정
                prnQueue = dlg.PrintQueue;
                prnTkt = dlg.PrintTicket;

                //DrawingVisual을 생성하고 DrawingContext를 염
                DrawingVisual vis = new DrawingVisual();
                DrawingContext dc = vis.RenderOpen();
                Pen pen = new Pen(Brushes.Black, 1);

                //Rectangle은 여백을 뺀 페이지를 나타냄
                Rect rectPage = new Rect(marginPage.Left, marginPage.Top, 
                                         dlg.PrintableAreaWidth - (marginPage.Left + marginPage.Right), 
                                         dlg.PrintableAreaHeight - (marginPage.Top + marginPage.Bottom));

                //사용자 여백을 반영한 사각형 출력
                dc.DrawRectangle(null, pen, rectPage);

                //PrintableArea 프로퍼티를 보여주는 포맷팅된 텍스트 객체를 생성
                FormattedText formattedText = new FormattedText(String.Format("Hello, Printer! {0} x {1}",
                                                                dlg.PrintableAreaWidth / 96, dlg.PrintableAreaHeight / 96),
                                                                CultureInfo.CurrentCulture,
                                                                FlowDirection.LeftToRight,
                                                                new Typeface(new FontFamily("Times New Roman"), 
                                                                                FontStyles.Italic, FontWeights.Normal, FontStretches.Normal),
                                                                48, Brushes.Black);

                //포맷된 텍스트 스트링의 물리적 크기를 계산
                Size sizeText = new Size(formattedText.Width, formattedText.Height);

                //여백 내의 텍스트의 중앙점을 계산
                Point ptText = new Point(rectPage.Left + (rectPage.Width - formattedText.Width) / 2, 
                                         rectPage.Top + (rectPage.Height - formattedText.Height) / 2);

                //텍스트와 이를 둘러싸는 사각형 출력
                dc.DrawText(formattedText, ptText);
                dc.DrawRectangle(null, pen, new Rect(ptText, sizeText));

                //DrawingContext를 종료
                dc.Close();

                //끝으로 페이지를 인쇄
                dlg.PrintVisual(vis, Title);
            }
        }
        /// <summary>
        /// 페이지 설정 버튼 : PageMarginsDialog 실행
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SetupOnClick(object sender, RoutedEventArgs e)
        {
            //대화상자를 생성하고 PageMargins 프로퍼티를 초기화
            PageMarginsDialog dlg = new PageMarginsDialog();
            dlg.Owner = this;
            dlg.PageMargins = marginPage;

            if (dlg.ShowDialog().GetValueOrDefault())
            {
                //대화상자의 페이지 여백을 저장
                marginPage = dlg.PageMargins;
            }
        }
    }
}

 

 

 

반응형
반응형

찰스 페졸드의 WPF 를 읽으면서 정리한 인쇄(PrintEllipse) 소스.

책을 읽으면서 직접 코딩을 하면서 정리했던 소스들을 그대로 옮겨 보았다.

 

using System;
using System.Printing;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace PrintEllipse
{
    public class PrintEllipse : Window
    {
        private PrintTicket prntkt;

        [STAThread]
        public static void Main()
        {
            Application app = new Application();
            app.Run(new PrintEllipse());
        }

        public PrintEllipse()
        {
            Title = "Print Ellipse";
            FontSize = 24;

            //윈도우 Content를 위한 스택 패널 생성
            StackPanel stack = new StackPanel();
            Content = stack;

            //인쇄를 위한 버튼 생성
            Button btn = new Button();
            btn.Content = "_Print...";
            btn.HorizontalAlignment = HorizontalAlignment.Center;
            btn.Margin = new Thickness(24);
            btn.Click += PrintOnClick;
            stack.Children.Add(btn);
        }

        private void PrintOnClick(object sender, RoutedEventArgs e)
        {
            PrintDialog dlg = new PrintDialog();
            if (prntkt != null) dlg.PrintTicket = prntkt;

            //페이지지정 라디오버튼을 활성화하기 위해서는 UserPageRangeEnabled를 true로 해야 한다.
            dlg.UserPageRangeEnabled = true;

            //ShowDialog는 널 값이 가능한 bool을 반환하게 정의되어 있다. 대화상자 클래스의 ShowDialog 메소드는 true/false/null을 반환한다.
            //사용자가 인쇄 버튼을 클릭하면 true를, 취소 버튼을 클릭하면 false를, 제목 옆의 닫기 버튼을 클릭하면 null을 반환한다.
            //GetValueOrDefault 메소드는 if문을 위해 결과가 항상 bool 형태가 되게 null 값을 false로 바꾸어 준다.
            if ((bool)dlg.ShowDialog().GetValueOrDefault())
            {
                prntkt = dlg.PrintTicket;

                //DrawingVisual을 생성하고 DrawingContext를 준비
                DrawingVisual vis = new DrawingVisual();
                DrawingContext dc = vis.RenderOpen();

                //타원을 출력
                //PrintableAreaWidth와 PrintableAreaHeight는 페이지의 인쇄 가능 영역을 참조하는 것이 아니라 장치 독립적인 단위(1/96)로 페이지의 전체 물리적인 크기를 가리킨다.
                dc.DrawEllipse(Brushes.LightGray, new Pen(Brushes.Black, 3),
                                new Point(dlg.PrintableAreaWidth / 2, dlg.PrintableAreaHeight / 2),
                                dlg.PrintableAreaWidth / 2 - 10, dlg.PrintableAreaHeight / 2 - 10);

                //DrawingCOntext를 닫음
                dc.Close();

                //끝으로 페이지를 인쇄
                dlg.PrintVisual(vis, "My First Print Job");
            }
        }
    }
}
반응형
반응형

Image img = new Image();
img.Source = new BitmapImage(new Uri(“pack://application:,,,/Assambly Name;component/Resources/aaa.png”, UriKind.RelativeOrAbsolute));

반응형

'C# 개발 > WPF' 카테고리의 다른 글

WPF에서 UserControl 마우스로 이동 처리 방법  (0) 2021.06.29
Observable Collection에서 Item 찾기  (0) 2019.01.10
C1 DataGrid 필터링 설정  (0) 2019.01.07
반응형

사용자 컨트롤을 마우스 좌측 버튼을 눌러서 이동시키고자 할 경우 유용하게 사용할 수 있는 코드이다.

MemoViewControl 클래스는 내가 만든 사용자 컨트롤이며, 이 컨트롤을 선택해서 마우스로 선택/이동 하는 기능을 수행한다.

MemoViewControl 부분을 각자가 만든 UserControl로 바꾸어서 사용하면 된다.

MemoViewControl에 대한 마우스 Down/Up/Move 이벤트를 아래와 같이 처리해서 사용하면 된다.

        private object movingObject;
        private double firstXPos, firstYPos;

        private void MemoView_PreviewMouseMove(object sender, MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed && sender == movingObject)
            {
                MemoViewControl memoCtnl = sender as MemoViewControl;
                Canvas canvas = memoCtnl.Parent as Canvas;
                // Horizontal
                double newLeft = e.GetPosition(canvas).X - firstXPos - canvas.Margin.Left;
                // newLeft inside canvas right-border?
                if (newLeft > canvas.Margin.Left + canvas.ActualWidth - memoCtnl.ActualWidth)
                    newLeft = canvas.Margin.Left + canvas.ActualWidth - memoCtnl.ActualWidth;
                // newLeft inside canvas left-border?
                else if (newLeft < canvas.Margin.Left)
                    newLeft = canvas.Margin.Left;

                memoCtnl.SetValue(Canvas.LeftProperty, newLeft);

                //Vertical
                double newTop = e.GetPosition(canvas).Y - firstYPos - canvas.Margin.Top;
                // newTop inside canvas bottom-border?
                // -- Bottom --
                if (newTop > canvas.Margin.Top + canvas.ActualHeight - memoCtnl.ActualHeight)
                    newTop = canvas.Margin.Top + canvas.ActualHeight - memoCtnl.ActualHeight;
                // newTop inside canvas top-border?
                // -- Top --
                else if (newTop < canvas.Margin.Top)
                    newTop = canvas.Margin.Top;

                memoCtnl.SetValue(Canvas.TopProperty, newTop);
            }
        }

        private void MemoView_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            selectMemo = (MemoViewControl)sender;
            Canvas canvas = selectMemo.Parent as Canvas;

            movingObject = null;
            
            Mouse.Capture(selectMemo);
        }              

        private void MemoView_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {            
            selectMemo = (MemoViewControl) sender;
            Canvas canvas = selectMemo.Parent as Canvas;

            firstXPos = e.GetPosition(selectMemo).X;
            firstYPos = e.GetPosition(selectMemo).Y;

            movingObject = sender;            
            Mouse.Capture(null);
        }

 

 

반응형

'C# 개발 > WPF' 카테고리의 다른 글

WPF에서 리소스에 등록된 이미지 가져오기  (0) 2021.08.23
Observable Collection에서 Item 찾기  (0) 2019.01.10
C1 DataGrid 필터링 설정  (0) 2019.01.07
반응형

마우스 Move 또는 Left Button Click 시에 마우스 포인트가 어떠한 선 위에 있는지를 체크하는 방법이다.

하기의 코드에 문제가 있거나, 개선이 필요한 부분이 있다면 의견 주시면 감사하겠습니다.

 

 

Function의 첫번째 파라미터는 선의 시작 포인트, 두번째 파라미터는 선의 종료 포인트, 세번째 파라미터는 마우스의 포인트를 말한다.

    public static bool CheckPointOnLine(Point startP, Point endP, Point point)
    {
        bool check = false;

        double dx = endP.X - startP.X;
        double dy = endP.Y - startP.Y;
        double dx1 = point.X - startP.X;
        double dy1 = point.Y - startP.Y;
        double a = 0, b = 0, c = 0;

        if (Math.Abs(dx) > 0 && Math.Abs(dy) < Math.Abs(dx))
        {
            if (dx * dx1 >= 0 && Math.Abs(dx1) <= Math.Abs(dx))
            {
                a = (dy * dx1);
                b = (dx * dy1);
                c = Math.Abs(dx * 5);
                if (Math.Abs(a - b) <= c)
                {
                    check = true;
                }
            }
        }
        else if (Math.Abs(dy) > 0)
        {
            if (dy * dy1 >= 0 && (Math.Abs(dy1) <= Math.Abs(dy)))
            {
                a = (dx * dy1);
                b = (dy * dx1);
                c = Math.Abs(dy * 5);
                if (Math.Abs(a - b) <= c)
                {
                    if (Math.Abs(a - b) <= c)
                    {
                        check = true;
                    }
                }
            }
        }

        return check;
    }

 

반응형
반응형

내가 만든 컨트롤 위에서 특정 위치에 마우스를 가져 갔을 때 풍선도움말로 사용자에게 메시지를 주고 싶을 때가 있다.

User Control 상의 특정 좌표에 마우스가 오면 풍선도움말을 제공하는 방법이다.

 

먼저 User Control에 대한 핸들 정보를 가져와야 한다.

IWin32Window window = Control.FromHandle(사용자컨트롤.Handle);

//툴팁 생성

ToolTip toolTip = new ToolTip();

toolTip.AutomaticDelay = 500;

toolTip.AutoPopDelay = 5000;
toolTip.InitialDelay = 500;
toolTip.ReshowDelay = 100;

MouseHover 이벤트에서 특정 조건에 맞을 경우 아래의 내용으로 Show를 하면 풍선 도움말이 제공된다.

if (조건이 참이면) {

    toolTip.Show("풍선도움말", window, X좌표, Y좌표);

} else { //그렇지 않을 경우 풍선도움말을 숨긴다.

    toolTip.Hide(window);

}

 

 

반응형
반응형

실제 생성한 Form의 소스가 Form1.cs 라고 하자. 

해당 폼을 개발하면서 UI/Event/Biz. 로직 등을 개발하다보면 Form1.cs파일의 사이즈가 점점 커지게 되고 해당 소스를 유지보수 하기도 불편하게 된다.

이러한 문제를 피하기 위해서 Form1.cs파일에서는 폼과 직접 연관되는 UI 영역만 커버하고 각 컨트롤의 이벤트 처리하는 영역은 별도의 클래스를 만들어서 처리할 수 있게 된다.

이렇게 하면 소스 즉 클래스에 대한 책임과 권한을 명확하게 분리하고 개발 및 유지보수가 편리해진다.

이렇게 설정하기 위해서는 WinForm 소스가 있는 프로젝트 파일에 아래와 같이 설정을 하면 된다.

 

<Compile Include="Form1.cs">

    <SubType>Form</SubType>

</Compile>

<Compile Include="Form1.Designer.cs">

    <DependentUpon>Form1.cs</DependentUpon>

</Compile>

<Compile Include="Form1.Event.cs">

    <DependentUpon>Form1.cs</DependentUpon>

    <SubType>Form</SubType>

</Compile>

반응형
반응형

한 주의 시작요일을 일요일로 했을 경우의 주차 정보 가져오기

Console.WriteLine("2015.01.01 주차는 " + GetWeekNumber(2015, 01, 01, DayOfWeek.Sunday));
Console.WriteLine("2015.02.01 주차는 " + GetWeekNumber(2015, 02, 01, DayOfWeek.Sunday));

 

한주의 시작요일을 월요일로 했을 경우의 주차 정보 가져오기
Console.WriteLine("2015.01.01 주차는 " + GetWeekNumber(2015, 01, 01, DayOfWeek.Monday));
Console.WriteLine("2015.02.01 주차는 " + GetWeekNumber(2015, 02, 01, DayOfWeek.Monday));

 

public static int GetWeekOfYear(DateTime sourceDate, CultureInfo cultureInfo, DayOfWeek dayOfWeek)
{
    if (cultureInfo == null)
    {
        cultureInfo = CultureInfo.CurrentCulture;
    }

    //해당 주의 첫째 요일 전까지 4일 이상이 있는 첫째 주가 해당 연도의 첫째 주가 되도록 지정
    CalendarWeekRule calendarWeekRule = CalendarWeekRule.FirstFourDayWeek;
    //주의 시작요일이 일요일 또는 월요일인지 확인. dayOfWeek가 일/월이 아닌 경우 월요일로 설정
    DayOfWeek firstDayOfWeek = cultureInfo.DateTimeFormat.FirstDayOfWeek;
    if (dayOfWeek == DayOfWeek.Sunday || dayOfWeek == DayOfWeek.Monday) 
    {
        firstDayOfWeek = dayOfWeek;
    } else firstDayOfWeek = DayOfWeek.Monday;
    
    int WeekOfYear = cultureInfo.Calendar.GetWeekOfYear(sourceDate, calendarWeekRule, firstDayOfWeek);

    return WeekOfYear;
}
반응형
반응형

GDI+를 이용해서 특정 이미지 또는 특정 위치에 글자를 정렬하고 싶을 때는 StringFormat을 이용하면 된다.

아래는 GDI+에서 Rectangle 영역에서 문자에 대한 Left/Center/Right 정렬을 하기 위해서 구현한 소스의 일부분이다.

 

//헤더 정렬이 Left일 경우
if (columns[i].HeaderAlign == HorizontalAlignment.Left)
{
    StringFormat sf = new StringFormat();
    sf.LineAlignment = StringAlignment.Center;
    sf.Alignment = StringAlignment.Near;
    Rectangle colRec = new Rectangle(startVSplitePos + leftHeaderWidth, 0, columns[i].Width, columns[i].Height);
    graphics.DrawString(columns[i].Text, headerFont, darkBlueBrush, colRec, sf);
}
else if (columns[i].HeaderAlign == HorizontalAlignment.Right) //헤더 정렬이 Right일 경우
{
    StringFormat sf = new StringFormat();
    sf.LineAlignment = StringAlignment.Center;
    sf.Alignment = StringAlignment.Far;
    Rectangle colRec = new Rectangle(startVSplitePos + leftHeaderWidth, 0, columns[i].Width, columns[i].Height);
    graphics.DrawString(columns[i].Text, headerFont, darkBlueBrush, colRec, sf);
}
else if (columns[i].HeaderAlign == HorizontalAlignment.Center) //헤더 정렬이 Center일 경우
{
    StringFormat sf = new StringFormat();
    sf.LineAlignment = StringAlignment.Center;
    sf.Alignment = StringAlignment.Center;
    Rectangle colRec = new Rectangle(startVSplitePos + leftHeaderWidth, 0, columns[i].Width, columns[i].Height);
    graphics.DrawString(columns[i].Text, headerFont, darkBlueBrush, colRec, sf);
}

반응형

+ Recent posts