Ответы пользователя по тегу WPF
  • Как сделать в DataGrid колонку с текстом и и другой таблицей?

    @Voucik
    Вот пример:
    Создаём табличку с вложенной таблицей DataTemplate.
    <DataGrid
                    Name="GvHeader"                     
                    AutoGenerateColumns="False"                                                 
                    HorizontalScrollBarVisibility="Auto"
                    CanUserDeleteRows="False"  
                    CanUserAddRows="False"            
                    CanUserResizeColumns="True"
                    CanUserReorderColumns="False"
                    CanUserResizeRows="False"
                    AllowDrop="False"
                    RowDetailsVisibilityMode="Collapsed"
                    IsReadOnly="True" ClipboardCopyMode="ExcludeHeader" SelectionMode="Single">
    
                <DataGrid.RowStyle>
                    <Style TargetType="{x:Type DataGridRow}">
                        <EventSetter Event="MouseDown"  Handler="HeaderRowMouseDown"/>
                        <EventSetter Event="Unselected" Handler="HeaderRowUnselected"></EventSetter>
                    </Style>
                </DataGrid.RowStyle>
    
                <DataGrid.RowDetailsTemplate>
                    <DataTemplate>
                        <DataGrid x:Name="GvLines"                     
                                        AutoGenerateColumns="False"                                                 
                                        HorizontalScrollBarVisibility="Auto"
                                        CanUserDeleteRows="False"  
                                        CanUserAddRows="False"            
                                        CanUserResizeColumns="True"
                                        CanUserReorderColumns="False"
                                        CanUserResizeRows="False"
                                        AllowDrop="False"            
                                        IsReadOnly="True" ClipboardCopyMode="ExcludeHeader" SelectionMode="Single" 
                                       ItemsSource="{Binding Path=Lines}">
                            <DataGrid.Columns>
                                <DataGridTextColumn
                                            Header="B1"                                                                                  
                                            Binding="{Binding Path=B,Mode=OneWay}"/>
                                <DataGridTextColumn
                                            Header="B2"                                                                                  
                                            Binding="{Binding Path=BB,Mode=OneWay}"/>
                                <DataGridTextColumn
                                            Header="B3"                                                                                  
                                            Binding="{Binding Path=BBB,Mode=OneWay}"/>
                            </DataGrid.Columns>
                        </DataGrid>
                    </DataTemplate>
                </DataGrid.RowDetailsTemplate>
                <DataGrid.Columns>
    
                    <DataGridTextColumn
                                            Header="A1"                                                                                  
                                            Binding="{Binding Path=A,Mode=OneWay}"/>
                    <DataGridTextColumn
                                            Header="A2"                                                                                  
                                            Binding="{Binding Path=AA,Mode=OneWay}"/>
                    <DataGridTextColumn
                                            Header="A3"                                                                                  
                                            Binding="{Binding Path=AAA,Mode=OneWay}"/>
                </DataGrid.Columns>
            </DataGrid>


    Теперь создадим два класса для теста
    public class Header
        {
            public String A { get; private set; }
            public String AA { get; private set; }
            public String AAA { get; private set; }
    
            public List<Line> Lines { get; private set; } 
    
            public Header(string a, string aa, string aaa,ICollection<Line> lines)
            {
                A = a;
                AA = aa;
                AAA = aaa;
    
                Lines = new List<Line>();
                if (lines != null && lines.Count > 0)
                {
                    Lines.AddRange(lines);
                }
            }
        }

    И
    public class Line
        {
            public String B { get; private set; }
            public String BB { get; private set; }
            public String BBB { get; private set; }
    
            public Line(string b, string bb, string bbb)
            {
                B = b;
                BB = bb;
                BBB = bbb;
            }
        }

    Теперь перейдём в код формы и напишем следующий код.
    public partial class MainWindow : Window
        {
            public List<Header> header;
            public MainWindow()
            {
                InitializeComponent();
    
                //заполняем тестовыми данными
                header = new List<Header>
                {
                    new Header("a1", "a2", "a3", new List<Line>
                    {
                        new Line("a", "b", "c"),
                        new Line("d", "1", "2")
                    }),
                    new Header("a11", "a22", "a33", new List<Line>
                    {
                        new Line("b1", "b2", "b3"),
                        new Line("b11", "b2222", "b333"),
                        new Line("b1111", "b22", "b3"),
                        new Line("dsxfds", "sdfsdf", "sfsdf")
                    }),
                    new Header("a1", "a2", "a3", new List<Line>
                    {
                        new Line("bb1", "b1", "ab"),
                        new Line("bb2", "b2", "bb"),
                        new Line("bb3", "b3", "cb")
                    }),
                };
    
                GvHeader.ItemsSource = header;//связываем главную табличку с нашими данными
            }
    
            //собитие, которое происходит при RowUnselected (тоесть когда выделение строки пропадает)-прячет подтаблицу
            private void HeaderRowUnselected(object sender, RoutedEventArgs e)
            {
                if (sender == null)
                {
                    return;
                }
                var row = (DataGridRow)sender;
                row.DetailsVisibility = Visibility.Collapsed;
            }
            //собитие, которое происходит при MouseDown-показывает подтаблицу
            private void HeaderRowMouseDown(object sender, MouseButtonEventArgs e)
            {
                if (sender == null)
                {
                    return;
                }
                var row = (DataGridRow)sender;
                row.DetailsVisibility = row.DetailsVisibility == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
            }
        }

    22d55d41265b462701ddc786e3427b18.png

    Ещё можно посмотреть код тут.
    http://social.msdn.microsoft.com/Forums/ru-RU/f41b870b-cc74-45fe-872c-15dec9acf55a/c-wpf-rowdetailstemplate?forum=fordesktopru
    Ответ написан
    Комментировать
  • Не прорисовывается WPF control на WinForm-е

    @Voucik
    Вроде как WPF проблемно работает, на некоторых процессорах (по моему на атомах).
    Ответ написан
    Комментировать
  • Как правильно сделать привязку данных в wpf?

    @Voucik
    вот пример.
    WPF форма, где у нас два контрола: ComboBox - cmb и TextBox - tb
    <Window x:Class="WpfApplication1.MainWindow"
            xmlns="<a href="http://schemas.microsoft.com/winfx/2006/xaml/presentation">http://schemas.microsoft.com/winfx/2006/xaml/presentation</a>"
            xmlns:x="<a href="http://schemas.microsoft.com/winfx/2006/xaml">http://schemas.microsoft.com/winfx/2006/xaml</a>"
            xmlns:wpfApplication1="clr-namespace:WpfApplication1"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
            <ResourceDictionary>
                <wpfApplication1:ConverterNull x:Key="ConverterNull"/>
            </ResourceDictionary>
        </Window.Resources>
        <Grid>
            
            <Grid.RowDefinitions>
                <RowDefinition Height="30"></RowDefinition>
                <RowDefinition Height="5"></RowDefinition>
                <RowDefinition Height="30"></RowDefinition>
            </Grid.RowDefinitions>
    
            <ComboBox Name ="cmb" DisplayMemberPath="Value" SelectedValuePath = "id" ></ComboBox>
    
            <TextBox Name="tb" Grid.Row="2"  Text="{Binding ElementName=cmb, Path=SelectedItem.Value,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,Converter={StaticResource ConverterNull}}"></TextBox>
        </Grid>
    </Window>

    DisplayMemberPath="Value" - то что будет отображаться (значение)
    SelectedValuePath = "id" - ключ

    Text="{Binding ElementName=cmb,
    Path=SelectedItem.Value - поле нашего объекта, значение которого будет присваиваться нашему tb
    ,Mode=TwoWay, - означает, привязка на read и write (при этом у поля, нашего объекта, должен быть открыт set )
    UpdateSourceTrigger=PropertyChanged - ну и фичя которая отвечает, за update данных
    ,Converter={StaticResource ConverterNull - а тут добавляем ещё конвертер, дабы у нас обрабатывались пустые значения.
    }}"

    Для этого надо добавить конвертер в ресурсы (как тут)
    <Window.Resources>
            <ResourceDictionary>
                <wpfApplication1:ConverterNull x:Key="ConverterNull"/>
            </ResourceDictionary>
        </Window.Resources>


    ну и путь указать к самому классу конвертера
    xmlns:wpfApplication1="clr-namespace:WpfApplication1"

    А теперь сам код.
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Windows;
    using System.Windows.Data;
    
    namespace WpfApplication1
    {
        public partial class MainWindow : Window
        {
            private List<Info> info;
            public MainWindow()
            {
                InitializeComponent();
                info = new List<Info>
                {
                    new Info("a"),
                    new Info("b"),
                    new Info("c")
                };
    
                cmb.ItemsSource = info;
            }
        }
    
        public class Info
        {
            public Guid id { get; private set; }
            public string Value { get; set; }
    
            public Info(String val)
            {
                id = Guid.NewGuid();
                Value = val;
            }
        }
    
        sealed class ConverterNull : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                return value;
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                return value == null ? null : String.IsNullOrWhiteSpace(value.ToString()) ? null : value;
            }
        }
    }


    public class Info - наши данные
    sealed class ConverterNull : IValueConverter - конвертер
    присваиваем наши данные комбоБоксу cmb.ItemsSource = info;
    и всё.
    Ответ написан
    Комментировать