블로그 이미지
Kanais
Researcher & Developer 퍼즐을 완성하려면 퍼즐 조각들을 하나 둘씩 맞춰나가야 한다. 인생의 퍼즐 조각들을 하나 둘씩 맞춰나가다 보면 인생이란 퍼즐도 완성되는 날이 오려나...?

calendar

1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30

Notice

04-27 19:20

Recent Post

Recent Comment

Recent Trackback

Archive

2024. 1. 4. 10:57 Programming/WPF

개발환경

OS : Window 10 x64 ver.22H2

DevTool : VS2019  ver.16.11.29

Framework : .NET Framework 4.8

Other : DevExpress 22.2

 

ScrollViewer에 ListBox를 배치하고 동적으로 CustomControl을 생성 및 삭제 하는 방법에 대한 글임.

CustromControl은 Label을 2개 가지고 있는 Control이며, MultiTrigger를 사용해서 Selected, Focused Conditions을 추가함

 

WPF MVVM 패턴을 사용함.

 

View.xaml

<ScrollViewer VerticalScrollBarVisibility="Auto">
   <ListBox Width="320" Height="400" BorderThickness="0"
            SelectedItem="{Binding SelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
            SelectedIndex="{Binding SelectedIndex, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
            ItemsSource="{Binding ItemCollection, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
      <ListBox.Resources>
         <Style TargetType="ListBoxItem">
            <Setter Property="Template">
               <Setter.Value>
                  <ControlTemplate TargetType="ListBoxItem">
                     <Border BorderThickness="{TemplateBinding Border.BorderThickness}"
                             Padding="{TemplateBinding Control.Padding}"
                             BorderBrush="{StaticResource BorderBrushColor}"
                             CornerRadius="5" Height="50" Margin="0,5,0,5"
                             Name="Bd" SnapsToDevicePixels="True">
                        <ContentPresenter x:Name="content" Content="{TemplateBinding ContentControl.Content}" 
                                          ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
                                          ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}"
                                          HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
                                          VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}"
                                          SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
                      </Border>
                      <ControlTemplate.Triggers>
                         <MultiTrigger>
                            <MultiTrigger.Conditions>
                               <Condition Property="Selector.IsSelectionActive" Value="False"/>
                               <Condition Property="Selector.IsSelected" Value="True"/>
                            </MultiTrigger.Conditions>
                            <Setter Property="Panel.Background" TargetName="Bd" Value="{StaticResource TwoLableBGColor_mouseOver}"/>
                            <Setter Property="Border.BorderBrush" TargetName="Bd" Value="Transparent"/>
                         </MultiTrigger>
                         <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="Selector.IsSelectionActive" Value="True"/>
                                <Condition Property="Selector.IsSelected" Value="True"/>
                            </MultiTrigger.Conditions>
                            <Setter Property="Panel.Background" TargetName="Bd" Value="{StaticResource TwoLableBGColor_checked}"/>
                            <Setter Property="Foreground" Value="{StaticResource TwoLableFontColor_checked}"/>
                            <Setter Property="Border.BorderBrush" TargetName="Bd" Value="Transparent"/>
                         </MultiTrigger>
                         <Trigger Property="UIElement.IsMouseOver" Value="True">
                            <Setter Property="Panel.Background" TargetName="Bd" Value="{StaticResource TwoLableBGColor_mouseOver}"/>
                            <Setter Property="Foreground" Value="{StaticResource TwoLableFontColor_checked}"/>
                            <Setter Property="Border.BorderBrush" TargetName="Bd" Value="Transparent"/>
                         </Trigger>
                         <Trigger Property="UIElement.IsEnabled" Value="False">
                            <Setter Property="TextElement.Foreground" TargetName="Bd">
                               <Setter.Value>
                                  <DynamicResource ResourceKey="{x:Static SystemColors.GrayTextBrushKey}" />
                               </Setter.Value>
                            </Setter>
                         </Trigger>
                      </ControlTemplate.Triggers>
                   </ControlTemplate>
                </Setter.Value>
             </Setter>
          </Style>
       </ListBox.Resources>
       <dxmvvm:Interaction.Behaviors>
          <dxmvvm:EventToCommand EventName="SelectionChanged" Command="{Binding SelectedButtonCommand}" CommandParameter="{Binding SelectedItem}"/>
       </dxmvvm:Interaction.Behaviors>
   </ListBox>
</ScrollViewer>

 

 

ViewModel.cs

View의 DataContext Class

    public class ViewModel
    {
        public ObservableCollection<TwoLabel> ItemCollection { get; set; }

        public int SelectedIndex
        {
            get => GetValue<int>();
            set => SetValue(value);
        }

        public object SelectedItem
        {
            get => GetValue<object>();
            set => SetValue(value);
        }

        public ICommand ButtonCommand => new DelegateCommand<object>(ButtonCommandMethod);
        public ICommand<object> SelectedButtonCommand => new DelegateCommand<object>(SelectedButtonCommandMethod);

        public PamProUserViewModel()
        {
            ItemCollection = new ObservableCollection<PamProTwoLabel>();
        }

        private void ButtonCommandMethod(object obj)
        {
            string param = obj as string;
            switch (param)
            {
                case "add": AddUserButtonCommandMethod(); break;
                default: break;
            }
        }

        private void AddUserButtonCommandMethod()
        {
            TwoLabel button = new TwoLabel()
            {
                ButtonCode = DateTime.Now.ToString(),
                TextTitle = "Operator",
                TextDescription = "Description"
            };
            button.SetText("Operator", "Description");
            ItemCollection.Add(button);
        }

        private void SelectedButtonCommandMethod(object obj)
        {
            if (obj is TwoLabel button)
            {
                string code = button.ButtonCode;
                for (int i = 0; i < ItemCollection.Count; i++)
                {
                    if (ItemCollection[i].ButtonCode == code)
                    {
                        ItemCollection[i].SetForeground("select");
                    }
                    else
                    {
                        ItemCollection[i].SetForeground("unSelect");
                    }
                }
            }
        }
    }

 

 

CustomControl  TwoLabel

namespace CommonControls.Views
{
    [ToolboxItem(true)]
    public class TwoLabel : Label, INotifyPropertyChanged
    {
        #region properties

        [Category("버튼코드"), Description("용어코드")]
        public string ButtonCode { get; set; }
        
        [Category("TextTitle"), Description("지정할 텍스트")]
        public string TextTitle { get; set; }

        [Category("TextDescription"), Description("버튼 설명")]
        public string TextDescription { get; set; }

        #endregion

        #region Layout Controls

        private TextBlock descriptionTextBlock;
        public TextBlock DescriptionTextBlockControl
        {
            get => descriptionTextBlock;
            set
            {
                descriptionTextBlock = value;
                OnPropertyChangedMethod("DescriptionTextBlockControl");
            }
        }
        private TextBlock titleTextBlock;
        public TextBlock TitleTextBlockControl
        {
            get => titleTextBlock;
            set
            {
                titleTextBlock = value;
                OnPropertyChangedMethod("TitleTextBlockControl");
            }
        }

        #endregion

        public TwoLabel() : base()
        {
            SetDefaultProperties();
            CreateContent();
            CreateStyle();
        }

        public event PropertyChangedEventHandler PropertyChanged;

        // Set default properties of PamProIconDescriptionButton
        private void SetDefaultProperties()
        {
            HorizontalContentAlignment = HorizontalAlignment.Stretch;
            VerticalContentAlignment = VerticalAlignment.Center;
            Loaded += OnLoaded;
        }

        private void OnPropertyChangedMethod([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        // IconDescriptionButton Style setting
        private void CreateStyle()
        {
            Height = 50;
            MinWidth = 200;
            Margin = new Thickness(0, 5, 0, 5);
            Background = new SolidColorBrush(Colors.Transparent);
            BorderThickness = new Thickness(0);
            BorderBrush = new SolidColorBrush(Colors.Transparent);
            VerticalAlignment = VerticalAlignment.Center;
        }

        // Create the IconDescriptionButton Content layout
        private void CreateContent()
        {
            StackPanel rootStackPanel = CreateStackPanel();

            TitleTextBlockControl = CreateTitleLabelContent();
            DescriptionTextBlockControl = CreateDescLabelContent();

            _ = rootStackPanel.Children.Add(TitleTextBlockControl);
            _ = rootStackPanel.Children.Add(DescriptionTextBlockControl);

            Content = rootStackPanel;
        }

        // Create title Label control
        private TextBlock CreateTitleLabelContent()
        {
            TextBlock titleLabel = new TextBlock
            {
                Width = 80,
                FontSize = 20,
                FontWeight = FontWeights.Bold,
                Foreground = Brushes.Black,
                VerticalAlignment = VerticalAlignment.Center,
                HorizontalAlignment = HorizontalAlignment.Left,
                Margin = new Thickness(6, 0, 0, 0)
            };

            return titleLabel;
        }

        // Create StackPanel controls (root, branch)
        private StackPanel CreateStackPanel()
        {
            StackPanel stackPanel = new StackPanel
            {
                VerticalAlignment = VerticalAlignment.Center,
                Background = Brushes.Transparent
            };

            stackPanel.Orientation = Orientation.Horizontal;

            return stackPanel;
        }

        // Craete description Label control
        private TextBlock CreateDescLabelContent()
        {
            TextBlock descLabel = new TextBlock
            {
                FontSize = 12,
                TextWrapping = TextWrapping.Wrap,
                Foreground = Brushes.Black,
                VerticalAlignment = VerticalAlignment.Center,
                HorizontalAlignment = HorizontalAlignment.Stretch,
                Margin = new Thickness(15, 0, 0, 0)
            };

            return descLabel;
        }
        

        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            TitleTextBlockControl.Text = TextTitle;
            DescriptionTextBlockControl.Text = TextDescription;
        }

        public void SetText(string _title, string _desc)
        {
            if (_title != null && !_title.Equals(""))
            {
                TitleTextBlockControl.Text = _title;
                TextTitle = _title;
            }
            if (_desc != null && !_desc.Equals(""))
            {
                DescriptionTextBlockControl.Text = _desc;
                TextDescription = _desc;
            }
        }

        public void SetForeground(string isSelection)
        {
            if (isSelection.Equals("select"))
            {
                DescriptionTextBlockControl.Foreground = new SolidColorBrush(Colors.White);
                TitleTextBlockControl.Foreground = new SolidColorBrush(Colors.White);
            }
            else
            {
                DescriptionTextBlockControl.Foreground = new SolidColorBrush(Colors.Black);
                TitleTextBlockControl.Foreground = new SolidColorBrush(Colors.Black);
            }
        }
    }
}

 

 

posted by Kanais