Пользовательский элемент управления C# WPF
Привет
Мне нужно использовать пользовательский элемент управления.
Я использую этот код XAML :
<UserControl x:Class="WpfClickableImage.ControlClickableImage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="UC" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" > <StackPanel> <Button Click="Button_Click" Margin="10" HorizontalAlignment="Center" ToolTip="Click on Fred"> <Button.Template> <ControlTemplate> <Border x:Name="theBorder" BorderBrush="Transparent" BorderThickness="2"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Image Grid.Column="0" Source="{Binding ElementName=UC, Path=Image}" Width="{Binding ElementName=UC, Path=ImageWidth}" Height="{Binding ElementName=UC, Path=ImageHeight}"/> <StackPanel Grid.Column="1" Orientation="Vertical" Margin="5"> <TextBlock Text="{Binding ElementName=UC, Path=Text1}" Margin="10,0,0,0"/> <TextBlock Text="{Binding ElementName=UC, Path=Text2}" Margin="10,0,0,0"/> </StackPanel> </Grid> </Border> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="BorderBrush" TargetName="theBorder" Value="LightSkyBlue"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Button.Template> </Button> </StackPanel> </UserControl>
А за спиной КС :
namespace WpfClickableImage { /// <summary> /// Logique d'interaction pour ControlClickableImage.xaml /// </summary> public partial class ControlClickableImage : UserControl { public ControlClickableImage() { InitializeComponent(); } public ImageSource Image { get { return (ImageSource)GetValue(ImageProperty); } set { SetValue(ImageProperty, value); } } // Using a DependencyProperty as the backing store for Image. This enables animation, styling, binding, etc... public static readonly DependencyProperty ImageProperty = DependencyProperty.Register("Image", typeof(ImageSource), typeof(ControlClickableImage), new UIPropertyMetadata(null)); public ImageSource ImageBack { get { return (ImageSource)GetValue(ImageBackProperty); } set { SetValue(ImageBackProperty, value); } } // Using a DependencyProperty as the backing store for ImageBack. This enables animation, styling, binding, etc... public static readonly DependencyProperty ImageBackProperty = DependencyProperty.Register("ImageBack", typeof(ImageSource), typeof(ControlClickableImage), new UIPropertyMetadata(null)); public double ImageWidth { get { return (double)GetValue(ImageWidthProperty); } set { SetValue(ImageWidthProperty, value); } } // Using a DependencyProperty as the backing store for ImageWidth. This enables animation, styling, binding, etc... public static readonly DependencyProperty ImageWidthProperty = DependencyProperty.Register("ImageWidth", typeof(double), typeof(ControlClickableImage), new UIPropertyMetadata(16d)); public double ImageHeight { get { return (double)GetValue(ImageHeightProperty); } set { SetValue(ImageHeightProperty, value); } } // Using a DependencyProperty as the backing store for ImageHeight. This enables animation, styling, binding, etc... public static readonly DependencyProperty ImageHeightProperty = DependencyProperty.Register("ImageHeight", typeof(double), typeof(ControlClickableImage), new UIPropertyMetadata(16d)); public string Text1 { get { return (string)GetValue(Text1Property); } set { SetValue(Text1Property, value); } } // Using a DependencyProperty as the backing store for Text. This enables animation, styling, binding, etc... public static readonly DependencyProperty Text1Property = DependencyProperty.Register("Text1", typeof(string), typeof(ControlClickableImage), new UIPropertyMetadata("")); public string Text2 { get { return (string)GetValue(Text2Property); } set { SetValue(Text2Property, value); } } // Using a DependencyProperty as the backing store for Text. This enables animation, styling, binding, etc... public static readonly DependencyProperty Text2Property = DependencyProperty.Register("Text2", typeof(string), typeof(ControlClickableImage), new UIPropertyMetadata("")); public bool IsChecked { get { return (bool)GetValue(IsCheckedProperty); } set { SetValue(IsCheckedProperty, value); } } // Using a DependencyProperty as the backing store for IsChecked. This enables animation, styling, binding, etc... public static readonly DependencyProperty IsCheckedProperty = DependencyProperty.Register("IsChecked", typeof(bool), typeof(ControlClickableImage), new UIPropertyMetadata(false)); private void Button_Click(object sender, RoutedEventArgs e) { this.IsChecked = !IsChecked; // swap images ImageSource temp = this.Image; this.Image = this.ImageBack; this.ImageBack = temp; //les 2 events sont declenches ici if (this.IsChecked) OnCheckedChanged(this, e); else if (!this.IsChecked ) OnUnCheckChanged(this, e); } // event perso Checked public static readonly RoutedEvent CheckedEvent = EventManager.RegisterRoutedEvent( "Checked", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(ControlClickableImage)); // Provide CLR accessors for the event public event RoutedEventHandler Checked { add { AddHandler(CheckedEvent, value); } remove { RemoveHandler(CheckedEvent, value); } } // event perso UnChecked public static readonly RoutedEvent UnCheckedEvent = EventManager.RegisterRoutedEvent( "UnChecked", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(ControlClickableImage)); // Provide CLR accessors for the event public event RoutedEventHandler UnChecked { add { AddHandler(UnCheckedEvent, value); } remove { RemoveHandler(UnCheckedEvent, value); } } // methods charge de raiser les 2 events private void OnCheckedChanged(ControlClickableImage controlClickableImage, RoutedEventArgs e) { RoutedEventArgs newEventArgs = new RoutedEventArgs( ControlClickableImage.CheckedEvent); newEventArgs.Source = controlClickableImage; RaiseEvent(newEventArgs); } private void OnUnCheckChanged(ControlClickableImage controlClickableImage, RoutedEventArgs e) { RoutedEventArgs newEventArgs = new RoutedEventArgs(ControlClickableImage.UnCheckedEvent); newEventArgs.Source = controlClickableImage; RaiseEvent(newEventArgs); } } }
In my application : <Window x:Class="WpfClickableImage.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:my="clr-namespace:WpfClickableImage" Title="Window1" Height="300" Width="300"> <StackPanel> <my:ControlClickableImage x:Name="yourcontrol" Image="calendar.png" ImageBack="worldwallpaper.jpg" Text1="ControlImageClickable" Text2="Description" HorizontalAlignment="Left" VerticalAlignment="Top" ImageWidth="20" ImageHeight="20" Margin="10" Checked="ControlClickableImage_Checked" UnChecked="ControlClickableImage_UnChecked"> </my:ControlClickableImage> </StackPanel> </Window>
А за КС по моему заявлению :
namespace WpfClickableImage { /// <summary> /// Logique d'interaction pour Window1.xaml /// </summary> public partial class Window1 : Window { public Window1() { InitializeComponent(); } private void ControlClickableImage_Checked(object sender, RoutedEventArgs e) { ControlClickableImage ctl = e.Source as ControlClickableImage; MessageBox.Show(ctl.IsChecked.ToString() + " ; " + ctl.Text1 + " ; " + ctl.Text2); } private void ControlClickableImage_UnChecked(object sender, RoutedEventArgs e) { ControlClickableImage ctl = e.Source as ControlClickableImage; MessageBox.Show(ctl.IsChecked.ToString() + " ; " + ctl.Text1 + " ; " + ctl.Text2); } } }
Это работа.
Но, прежде чем, на моем флажке, я отправлю эту привязку :
IsChecked="{Binding bChecked}"
Чтобы проверить все например :
private void btnTous_Click(object sender, RoutedEventArgs e) { foreach (var item in LstIlots) { item.bChecked = true; } }
Но это свойство IsChecked не работает в моем пользовательском элементе управления.
Как я могу включить этот параметр ?
Спасибо.
Что я уже пробовал:
Я пытаюсь добавить этот флажок установлен обязательный bChecked в моем коде приложения XAML :
<my:ControlClickableImage x:Name="yourcontrol" Image="calendar.png" ImageBack="worldwallpaper.jpg" Text1="ControlImageClickable" Text2="Description" HorizontalAlignment="Left" VerticalAlignment="Top" ImageWidth="20" ImageHeight="20" Margin="10" Checked="ControlClickableImage_Checked" UnChecked="ControlClickableImage_UnChecked" IsChecked="{Binding bChecked}> </my:ControlClickableImage>
Но это не работа.
Заранее спасибо.
Bernhard Hiller
Чего вы ожидаете? И что же происходит вместо этого? Я не вижу никакого поведения, связанного с этим свойством.
Steve15f
Привет
В моем пользовательском элементе управления C# у меня есть
общественная bool этот флажок установлен
{
get { return (bool)GetValue(IsCheckedProperty); }
set { SetValue(IsCheckedProperty, value); }
}
Мне нужно проверить / снять флажок с моей кнопки, если bChecked является истинным или ложным
Спасибо
johannesnestler
Я думаю, что ваш вопрос сбивает с толку. "пользовательский пользовательский элемент управления"... "пользовательский контроль" и "пользовательский контроль" - это термины с особым значением в WPF (просто первый хит в Google для меня: https://stackoverflow.com/questions/1322451/what-is-the-difference-between-user-control-custom-control-and-component ).
Что вы хотели: customcontrol с темой по умолчанию (generic) (визуальное дерево будет заменено позже)
То, что вы создали: UserControl с кодом позади (визуальное дерево не будет заменено позже)
Поэтому я предлагаю создать customcontrol из вашего кода и использовать TemplateBindings внутри его визуального дерева (XAML) для таких вещей, как ваше "проверенное" состояние элемента, который будет представлять это состояние внутри визуального дерева вашего элемента управления. Если вы не знаете, о чем я говорю (очень вероятно - я бы предположил, что вы пришли из WinForms), лучше прочитайте некоторые основы WPF и элементов управления в документации, прежде чем идти дальше с этим... Эмпирическое правило: никогда не создавайте пользовательские элементы управления, если вы не знаете свой WPF внутри и снаружи, а если знаете, то делайте это правильно (поведение?)
Steve15f
Да, извините, я скажу пользовательский контроль
Моя Контрольная работа, но мне тоже нужно проверить свойство
Да, я родом из Winforms.
Вы можете дать мне больше информации ?
Я создал DLL с моим пользовательским элементом управления. Это неправильно ?
Я создал библиотеку типов проектов user controle WPF и вставляю свою DLL в свой проект.
Все в порядке но я не проверял собственность
johannesnestler
Не нужно оправдываться ;) Я просто хотел направить тебя в нужное русло...вы должны понять, как работают dependencyproperties, Control theming, visual trees и так далее... это предотвратит такой беспорядок для вашего следующего элемента управления. Так что вам придется научиться делать вещи в WPF. Может быть, мое "эмпирическое правило" можно неправильно понять... То, что я хотел сказать - очень редко возникает необходимость в "контроле" в WPF, как вы использовали в WinForms, - потому что там вы, возможно, лучше работаете с шаблоном MVVM... Вещи, которые не могут быть объяснены в коротком QA-постинге...
Но я понимаю, что вам нужно быстрое решение: я бы начал здесь: я не вижу, чтобы вы что-то делали с IsChecked-свойством внутри вашего кода. так чего же вы ожидаете? Другими словами, как ваша проверенная информация представлена визуально? Подождите немного, я попытаюсь создать пример для вас, чтобы понять различные подходы, которые вы могли бы использовать здесь - может быть, тогда вы сможете увидеть решение...
Steve15f
Спасибо за ваш ответ. Извините и за мой английский.
Я бы изменил свой флажок на стиль кнопки. Я использовал это :
&ЛТ;флажок х:имя="cbxIlots" тег="{привязки strCodeIlot}" тип="{расширение StaticResource {х:тип выключатель}}" содержание="{привязки strDesIlot}" свойство FontSize="14" маржи="25,15,25,15" ширина="225" высота="45" этот флажок установлен="{привязки bChecked}" проверил="cbxIlots_Checked" снят="cbxIlots_Unchecked" /&ГТ;
Я установил стиль "togglebutton"в свой флажок.
Это работа, отличная.
Но мне нужна кнопка, с двумя текстами, например, заголовок, размер шрифта 14, жирный и ниже, текст, например, описание, размер шрифта 10, курсив.
И, если мой флажок установлен, изображение с синим фоном, а не с фиолетовым фоном, например.
Как я это делаю ?
Заранее спасибо. Если хорошее решение состоит в том, чтобы не использовать пользовательский элемент управления, я бы использовал отличное решение, чтобы получить свой результат.
Я могу работать с этим кодом в своем основном проекте XAML :
& lt;Window x: Class= " Plutus.SelectionIlot"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
описание:х="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns: my= " clr-пространство имен:BoutonsSelection;assembly=BoutonsSelection"
Title=" Sélection d'ilot "Height= "367" Width=" 884 "WindowStartupLocation= "Centercreen" ResizeMode= "NoResize" ShowInTaskbar=" False "Icon=" PlutusIcone.ico " >
& lt;window. resources>
& amp;lt;Setter Property= "Template">
& lt;сеттер.Значение>
& lt; ControlTemplate TargetType= "{x: type CheckBox} " >
& amp;lt;ориентация StackPanel="горизонтальная" >
&ЛТ;изображения X:имя="checkboxImage" Источник="изображения/btnNormal.формат PNG" ширина="32"/&ГТ;
< ContentPresenter/>
< / stackpanel>
< ControlTemplate.Триггеры>
&амп;ЛТ;триггер свойства="этот флажок установлен" значение="истинный"и GT;
&амп;ЛТ;сеттер выражение targetname="checkboxImage" собственность="источник" значение="изображения/btnChecked.формат PNG"/&ГТ;
< / триггер>
&ЛТ;MultiTrigger&ГТ;
&ЛТ;MultiTrigger.Условия>
& amp;lt;Condition Property=" IsMouseOver "Value= "True"/>
& amp;lt;Condition Property= "IsChecked" Value= "False"/>
&ЛТ;/multitrigger.Условия>
&амп;ЛТ;!--&амп;ЛТ;сеттер выражение targetname="checkboxImage" собственность="источник" значение="при наведении.формат PNG"/&ГТ;--&ГТ;
&ЛТ;/multitrigger&ГТ;
< / controltemplate.Триггеры>
< / controltemplate>
& lt;/сеттер.Значение>
< / сеттер>
& lt;сетка>
&ЛТ;решетки.columndefinitions&ГТ;
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
&ЛТ;решетки.rowdefinitions и GT;
& lt;Rowdefinition Height= "0.1*" />
& lt;Rowdefinition Height= "0.85*" />
& lt;Rowdefinition Height= "0.15*" />
<ScrollViewer VerticalScrollBarVisibility=сетка" авто".Столбец=Сетка "0".ColumnSpan=" 4 "Grid. Row=" 1 " >
&ЛТ;управления ItemsControl х:имя="lvDataBinding" HorizontalContentAlignment="растянуть" BorderThickness="0" маржи="10" сетки.Строка="1" фоне="{х:нуль}", что ItemsSource="{привязки LstIlots}" сетки.ColumnSpan= "4" передний план= "Белый">
&ЛТ;управления ItemsControl.свойства itemtemplate&ГТ;
<datatemplate>
< Border BorderBrush= "White"BorderThickness=" 1"CornerRadius=" 3"Margin=" 0,3 " Grid.ColumnSpan=" 0 "Background= "Transparent" HorizontalAlignment=" Left " Vert
johannesnestler
шаг за шагом Стив-давайте сначала найдем правильный подход к управлению поведением, а потом все должно быть решено таким же образом. Кстати. для таких вещей обычно просто контролируется видимость различных элементов управления (например, два текстовых поля с разным шрифтом и цветом друг над другом), что вы никогда не должны делать в WinForms (по соображениям производительности). Я пришел той же дорогой и думаю, что у меня есть чувство к "ментальным ловушкам" - извините за мой английский тоже-Я австриец...