Pull to refresh

Comments 14

Мне кажется, ты не прав в своем взгляде на свою жизнь :)

Вот смотри, у тебя был выбор, взять сторонню dll в свой проект.
Ты взял стороннюю dll, но с оговоркой, что пусть она будет от MS, а не от кого то там.
Это выбор смекалистого программиста. Уважаю.
И задача которую ты решил и показал всем, тоже достойна лицезрения мимо проходящих.

График и правда замечательный.
Там наверное не выделено жирным — в .NET 4 DataVisualization.Charts встроен
У меня появилось ощущение, что когда я запускаю свою программку написанную на .net, то в память загружаются все библиотеки .net. Поэтому я купил 16 Гб.
Спорить о качестве .NET не будем, мне ближе Unix-way со всеми вытекающими. В куче элементаршейших задач толи по незнанию, толи по непониманию архитектуры постоянно натыкаюсь на проблемы. Например ставить дефолтовый итем в комбо, в который данные грузятся биндингом. И такого добра куча. Но если надо, то надо…
SelectedItem тоже можно биндить.
Я не про SelectedItem, а про елемент типа «Выбетите цвет». Чтобы такое сделать надо городить огород с CompositeCollection
Вам нужен ComboBox с выборкой цвета? Если так, то я опять не понимаю, в чем проблема и зачем там CompositeCollection:
Вот несколько способов
<Window ...
        xmlns:sys="clr-namespace:System;assembly=mscorlib" 
        xmlns:local="clr-namespace:WpfApplication1">

    <Window.Resources>
        <ObjectDataProvider x:Key="ColorsInstance" ObjectType="{x:Type sys:Type}" MethodName="GetType">
            <ObjectDataProvider.MethodParameters>
                <sys:String>System.Windows.Media.Colors, PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</sys:String>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
        <!-- 1 вариант вообще без дополнительных классов, но в шаблоне ComboBoxItem биндинг нужно осуществялть к Name -->
        <ObjectDataProvider x:Key="AvailableColors1" ObjectInstance="{StaticResource ColorsInstance}" MethodName="GetProperties" />
        <!-- 2 и 3 способы через класс-хелпер -->
        <ObjectDataProvider x:Key="AvailableColors2" ObjectType="{x:Type local:ColorHelpers}" MethodName="GetAllColors"/>
        <ObjectDataProvider x:Key="AvailableColors3" ObjectType="{x:Type local:ColorHelpers}" MethodName="GetAppColors"/>

        <DataTemplate x:Key="ColorsComboBox1ItemTemplate" DataType="{x:Type ComboBoxItem}">
            <StackPanel Height="18" Margin="0,0,0,2" Orientation="Horizontal">
                <Border Width="30"
                        Background="{Binding Name}"
                        BorderBrush="DarkGray"
                        BorderThickness="1"
                        CornerRadius="2" />
                <TextBlock Margin="8,0,0,0" Text="{Binding Name}" />
            </StackPanel>
        </DataTemplate>
        <Style x:Key="ColorsComboBox1Style" TargetType="{x:Type ComboBox}">
            <Setter Property="HorizontalAlignment" Value="Center" />
            <Setter Property="VerticalAlignment" Value="Center" />
            <Setter Property="Width" Value="150" />
            <Setter Property="ItemTemplate" Value="{StaticResource ColorsComboBox1ItemTemplate}" />
        </Style>
        
        <DataTemplate x:Key="ColorsComboBox2ItemTemplate" DataType="{x:Type ComboBoxItem}">
            <StackPanel Height="18" Margin="0,0,0,2" Orientation="Horizontal">
                <Border Width="30"
                        Background="{Binding}"
                        BorderBrush="DarkGray"
                        BorderThickness="1"
                        CornerRadius="2" />
                <TextBlock Margin="8,0,0,0" Text="{Binding}" />
            </StackPanel>
        </DataTemplate>
        <Style x:Key="ColorsComboBox2Style" TargetType="{x:Type ComboBox}">
            <Setter Property="HorizontalAlignment" Value="Center" />
            <Setter Property="VerticalAlignment" Value="Center" />
            <Setter Property="Width" Value="150" />
            <Setter Property="ItemTemplate" Value="{StaticResource ColorsComboBox2ItemTemplate}" />
        </Style>
    </Window.Resources>

    <Grid x:Name="LayoutRoot">
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <ComboBox ItemsSource="{Binding Source={StaticResource AvailableColors1}}" SelectedValuePath="Name" Style="{StaticResource ColorsComboBox1Style}" />
        <ComboBox ItemsSource="{Binding Source={StaticResource AvailableColors2}}" Style="{StaticResource ColorsComboBox2Style}" Grid.Row="1" />
        <ComboBox ItemsSource="{Binding Source={StaticResource AvailableColors3}}" Style="{StaticResource ColorsComboBox2Style}" Grid.Row="2" />
        <ContentControl Content="{Binding Source={StaticResource AvailableColors3}}" HorizontalAlignment="Center" VerticalAlignment="Center" Width="150" Grid.Row="3">
            <ContentControl.ContentTemplate>
                <DataTemplate>
                    <Grid>
                        <ComboBox x:Name="Items" ItemsSource="{Binding}"/>
                        <TextBlock x:Name="DefaultText" Text="Выберите цвет" IsHitTestVisible="False" Visibility="Hidden" Margin="4,3" />
                    </Grid>
                    <DataTemplate.Triggers>
                        <Trigger SourceName="Items" Property="SelectedItem" Value="{x:Null}">
                            <Setter TargetName="DefaultText" Property="Visibility" Value="Visible"/>
                        </Trigger>
                    </DataTemplate.Triggers>
                </DataTemplate>
            </ContentControl.ContentTemplate>
        </ContentControl>
    </Grid>
</Window>

    public sealed class ColorHelpers
    {
        public enum AppColor : uint
        {
            Black = 0xFF000000,
            Blue = 0xFF0000FF,
            Brown = 0xFFA52A2A,
            Crimson = 0xFFDC143C,
            Cyan = 0xFF00FFFF
        }

        public static Color FromUInt32(uint argb)
        {
            var a = (byte)((argb & 0xff000000) >> 24);
            var r = (byte)((argb & 0x00ff0000) >> 16);
            var g = (byte)((argb & 0x0000ff00) >> 8);
            var b = (byte)(argb & 0x000000ff);
            return Color.FromArgb(a, r, g, b);
        }

        public static IEnumerable<string> GetAllColors()
        {
            return typeof(Colors).GetProperties(BindingFlags.Public | BindingFlags.Static).Select(p => p.Name);
        }


        public static IEnumerable<string> GetAppColors()
        {
            return typeof(AppColor).GetEnumNames(); //Enum.GetValues(typeof(AppColor)).GetNames()
        }
    }

в вашем примере я не смогу потом вернуться назад на пункт «Выберите цвет». Поэтому приходится делать как-то так:
<ComboBox">
            <ComboBox.ItemsSource>
                <CompositeCollection>
                    <ComboBoxItem>Выберите цвет</ComboBoxItem>
                    <CollectionContainer Collection="{Binding}" />
                </CompositeCollection>
            </ComboBox.ItemsSource>
        </ComboBox>


А отсутствие возможности добавить Value к ComboBoxItem порождает возню с SelectedValuePath и ошибки при выборе пункта «Выберите цвет». Хотя тут скорее привычки работы с HTML’ным SELECT сказываются
А-а-а-а. Так в таком случае (я так понимаю у вас необязательный выбор) лучше сделать кнопку а-ля ClearSelection. Наследуемся от ComboBox, создаем стиль, в котором меняем Template. В Popup со списком добавляем Button с командой по клику, которая ставил SelectedItem = null или SelectedIndex = -1. Там же делаем триггеры, чтобы показать ваш DefaultText и убрать эту кнопку если SelectedItem = null или SelectedIndex = -1.

Вот у контролов Telerik так сделано:


Понимаю, муторно, но если у вас есть Expression Blend, то такие вещи делаются 30 минут с обычными контролами. Если нет — нужно мучить босса/себя, чтобы его купить.
вот по этому я и написал что как то все сложно. А адепты запинусовали, наверное считая, что три килобайта кода для тупого комбо — это норма :) Хотя кто-то и сказал что WPF делает сложное легким, а легкое сложным :)
Помогло.

На Powershell потребовалось добавить несколько строк:

PowerShell:

Add-Type -AssemblyName WindowsFormsIntegration

$Chart_chart = $Form.FindName(«WinForm_canvas»)
# create chart object
$Chart = New-object System.Windows.Forms.DataVisualization.Charting.Chart
$Chart.Width = 500
$Chart.Height = 400
$Chart.Left = 40
$Chart.Top = 30

$Chart.ser

$chart.ChartAreas.Add(«Default»);
$Chart.Series.Add(«Series1»);
$chart.Series[«Series1»].ChartArea = «Default»;
#$chart.Series[«Series1»].ChartType = SeriesChartType.Line;

$axisXData = @(«a», «b», «c»)
$axisYData = @(0.1, 1.5, 1.9)
$chart.Series[«Series1»].Points.DataBindXY($axisXData, $axisYData);

$Chart_chart.Child = $Chart

XAML:

xmlns:wfi=«clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration»


Sign up to leave a comment.

Articles