0

Try to make an editable datagrid in wpf.

Figured out how to bind data to datagrid and edit them.

Figured out how to bing enum to combobox in datagrid with objectprovider by this answer.

However when i try change my program locale at runtime, the combobox items won't change it's content with locale resources.

Is there some way to make the combobox be able to bing an enum and able to locale with dynamic resources?

Here's my code:

<!-- App.xaml -->
<Application x:Class="DatagridComboLocale.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:DatagridComboLocale"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Locale/en-US.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>
<!-- Locale/en-US.xaml -->
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:sys="clr-namespace:System;assembly=mscorlib">
    <sys:String x:Key="Student">
        student
    </sys:String>
    <sys:String x:Key="Teacher">
        teacher
    </sys:String>

    <sys:String x:Key="FirstGrade">
        first grade
    </sys:String>
    <sys:String x:Key="SecondGrade">
        second grade
    </sys:String>
    <sys:String x:Key="ThirdGrade">
        third grade
    </sys:String>
</ResourceDictionary>
<!-- Locale/zh-CN.xaml -->
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:sys="clr-namespace:System;assembly=mscorlib">
    <sys:String x:Key="Student">
        学生
    </sys:String>
    <sys:String x:Key="Teacher">
        教师
    </sys:String>

    <sys:String x:Key="FirstGrade">
        一年级
    </sys:String>
    <sys:String x:Key="SecondGrade">
        二年级
    </sys:String>
    <sys:String x:Key="ThirdGrade">
        三年级
    </sys:String>
</ResourceDictionary>
<!-- MainWindow.xaml -->
<Window x:Class="DatagridComboLocale.MainWindow"
        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:core="clr-namespace:System;assembly=mscorlib"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:DatagridComboLocale"
        mc:Ignorable="d"
        Title="MainWindow" Height="300" Width="360">
    <Window.Resources>
        <DataTemplate x:Key="TableCheckboxDataTemplate">
            <Grid>
                <CheckBox Click="On_GridCheckBox_Checked" Uid="{Binding Uid}" IsChecked="{Binding IsSelected, Mode=TwoWay}"/>
            </Grid>
        </DataTemplate>

        <Style x:Key="CheckBoxStyle" TargetType="{x:Type DataGridCell}">
            <Setter Property="ContentTemplate" Value="{StaticResource TableCheckboxDataTemplate}"/>
        </Style>

        <ObjectDataProvider x:Key="IdentityEnumKey" MethodName="GetValues" ObjectType="{x:Type core:Enum}">
            <ObjectDataProvider.MethodParameters>
                <x:Type Type="local:Identity"/>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>

        <ObjectDataProvider x:Key="GradeEnumKey" MethodName="GetValues" ObjectType="{x:Type core:Enum}">
            <ObjectDataProvider.MethodParameters>
                <x:Type Type="local:Grade"/>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
    </Window.Resources>
    <Grid>
        <DataGrid x:Name="InfoTable" ItemsSource="{Binding}"  SelectionUnit="Cell" AutoGenerateColumns="False" CanUserAddRows="False">
            <DataGrid.Columns>
                <DataGridCheckBoxColumn  Header="Select" CellStyle="{StaticResource  CheckBoxStyle}">
                    <DataGridCheckBoxColumn.HeaderTemplate>
                        <DataTemplate>
                            <CheckBox Content="SelectAll" Uid="-1" Click="On_GridCheckBox_Checked" />
                        </DataTemplate>
                    </DataGridCheckBoxColumn.HeaderTemplate>
                </DataGridCheckBoxColumn>
                <DataGridTemplateColumn Header="Name" Width="*">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Grid>
                                <TextBlock Text="{Binding Name}" />
                            </Grid>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                    <DataGridTemplateColumn.CellEditingTemplate>
                        <DataTemplate>
                            <Grid>
                                <TextBox Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=Explicit}" />
                            </Grid>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellEditingTemplate>
                </DataGridTemplateColumn>
                <DataGridTemplateColumn Header="Identity" Width="*">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Grid>
                                <TextBlock Text="{Binding Identity}" />
                            </Grid>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                    <DataGridTemplateColumn.CellEditingTemplate>
                        <DataTemplate>
                            <ComboBox SelectedItem="{Binding Identity, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding Source={StaticResource IdentityEnumKey}}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellEditingTemplate>
                </DataGridTemplateColumn>
                <DataGridTemplateColumn Header="Grade" Width="*">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Grid>
                                <TextBlock Text="{Binding Grade}" />
                            </Grid>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                    <DataGridTemplateColumn.CellEditingTemplate>
                        <DataTemplate>
                            <ComboBox SelectedItem="{Binding Grade, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding Source={StaticResource GradeEnumKey}}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellEditingTemplate>
                </DataGridTemplateColumn>
                <DataGridTemplateColumn Header="Action" Width="*">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <StackPanel>
                                <Button Content="Edit" Click="on_grid_row_edit_button_click" />
                                <Button Content="Delete" Click="on_grid_row_delete_button_click" />
                            </StackPanel>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                    <DataGridTemplateColumn.CellEditingTemplate>
                        <DataTemplate>
                            <StackPanel>
                                <Button Content="Save" Click="on_grid_row_edit_save_button_click" />
                                <Button Content="Cancel" Click="on_grid_row_edit_cancel_button_click" />
                            </StackPanel>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellEditingTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>
// MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
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;

namespace DatagridComboLocale
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    /// 

    public class DisplayAttributeBasedObjectDataProvider : ObjectDataProvider
    {
        public object GetEnumValues(Enum enumObj)
        {
            var attribute = enumObj.GetType().GetRuntimeField(enumObj.ToString()).
                GetCustomAttributes(typeof(DisplayAttribute), false).
                SingleOrDefault() as DisplayAttribute;
            return attribute == null ? enumObj.ToString() : attribute.Description;
        }

        public List<object> GetShortListOfApplicationGestures(Type type)
        {
            var shortListOfApplicationGestures = Enum.GetValues(type).OfType<Enum>().Select(GetEnumValues).ToList();
            return
                shortListOfApplicationGestures;
        }
    }


    [AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
    public class DisplayAttribute : Attribute
    {
        public DisplayAttribute(string displayName)
        {
            ResourceDictionary localeDict = System.Windows.Application.Current.Resources.MergedDictionaries[0];
            string localeName = localeDict.FindName(displayName).ToString();
            Description = localeName == null ? displayName : localeName;
        }

        public string Description { get; set; }
    }


    public enum Identity
    {
        [Display("Student")]
        Student = 0,
        [Display("Teacher")]
        Teacher = 1,
    }

    public enum Grade
    {
        [Display("FirstGrade")]
        FirstGrade = 0,
        [Display("SecondGrade")]
        SecondGrade = 1,
        [Display("ThirdGrade")]
        ThirdGrade = 2
    }

    public struct InfoTableItem
    {
        public string name;
        public Identity identity;
        public Grade grade;
    }

    public partial class MainWindow : Window
    {

        public ObservableCollection<InfoTableItem> InfoTableData = new ObservableCollection<InfoTableItem>();
        public class InfoTableItem: INotifyPropertyChanged
        {
            private Int32 _uid { get; set; }
            private string _name { get; set; }
            private Identity _identity { get; set; }
            private Grade _grade { get; set; }
            private bool _isSelected { get; set; }

            public Int32 Uid
            {
                get { return _uid; }
                set { this._uid = value; OnPropertyChanged("Uid"); }
            }

            public string Name
            {
                get { return _name; }
                set { this._name = value; OnPropertyChanged("Name"); }
            }

            public Identity Identity
            {
                get { return _identity; }
                set { this._identity = value; OnPropertyChanged("Identity"); }
            }

            public Grade Grade
            {
                get { return _grade; }
                set { this._grade = value; OnPropertyChanged("Grade"); }
            }

            public bool IsSelected
            {
                get { return _isSelected; }
                set { this._isSelected = value; OnPropertyChanged("IsSelected"); }
            }

            public event PropertyChangedEventHandler PropertyChanged;
            void OnPropertyChanged(string name)
            {
                if (PropertyChanged != null)
                {
                    this.PropertyChanged(this, new PropertyChangedEventArgs(name));
                }
            }

            public InfoTableItem(Int32 uid, string name, Identity identity, Grade grade)
            {
                Uid = uid;
                Name = name;
                Identity = identity;
                Grade = grade;
                IsSelected = false;
            }
        }

        public MainWindow()
        {
            InitializeComponent();

            this.InfoTableData.Add(new InfoTableItem(122, "Jack", Identity.Student, Grade.FirstGrade));
            this.InfoTableData.Add(new InfoTableItem(98, "Mike", Identity.Student, Grade.ThirdGrade));
            this.InfoTableData.Add(new InfoTableItem(42, "Andrew", Identity.Teacher, Grade.FirstGrade));

            this.InfoTable.DataContext = this.InfoTableData;

            System.Windows.Application.Current.Resources.MergedDictionaries[0] = new ResourceDictionary() { Source = new Uri($"Locale/zh-CN.xaml", UriKind.Relative) };
        }

        private void On_GridCheckBox_Checked(object sender, RoutedEventArgs e)
        {
            var CurCheckBox = sender as CheckBox;
            var CurCheckBoxUID = int.Parse(CurCheckBox.Uid);

            if (CurCheckBoxUID == -1)
            {
                foreach (var item in this.InfoTableData)
                {
                    item.IsSelected = true;
                }

                CurCheckBox.Uid = "-2";
                return;
            }
            else if (CurCheckBoxUID == -2)
            {
                foreach (var item in this.InfoTableData)
                {
                    item.IsSelected = false;
                }

                CurCheckBox.Uid = "-1";
                return;
            }

            var CurItemIsSelected = this.InfoTableData[CurCheckBoxUID].IsSelected;
            this.InfoTableData[CurCheckBoxUID].IsSelected = (CurItemIsSelected ? false : true);
        }

        private void on_infotable_checkbox_checked(object sender, RoutedEventArgs e)
        {

        }


        private void on_grid_row_edit_button_click(object sender, RoutedEventArgs e)
        {

        }

        private void on_grid_row_delete_button_click(object sender, RoutedEventArgs e)
        {

        }

        private void on_grid_row_edit_save_button_click(object sender, RoutedEventArgs e)
        {

        }

        private void on_grid_row_edit_cancel_button_click(object sender, RoutedEventArgs e)
        {

        }
    }
}
Hellagur
  • 93
  • 7

0 Answers0