Гость
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / ContentControl вместо наследования? / 14 сообщений из 14, страница 1 из 1
16.02.2012, 01:52
    #37664359
jupiter
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ContentControl вместо наследования?
Здравствуйте.
Если обсуждалось уже - не бить ногами, я новичок.
Пробовал сделать свой базовый класс контрола, на основе которого сделать другие свои классы за счет наследования. Типа,

Родительский класс:
<UserControl x:Class="MyBase"....

Потомок:
<MyBase x:Class="MyControl"....

(Это упрощенно, на самом деле там еще неймспейсы и др.)

Так вот, это не работает. Если я использую события, но метод-обработчик события не виден в базовом классе, базовый класс выдает ошибку выполнения. Будто бы я указал имя не существующего метода.

Если я не использую событий, то ошибки не возникает, но отображаются контролы только класса-наследника, а базоый класс вообще не отображается.

Я поискал инфу, в том числе и на этом форуме. Правильно ли я понял, что визуальное наследование в SilverLight не риализовано и использоваться не должно? И правильно ли я понял, что можно достичь того же результата путем применения ContentControl, в котором нужно реализовать общую функциональность? Вместо наследования применяем агрегацию.

Спасибо
...
Рейтинг: 0 / 0
16.02.2012, 09:36
    #37664500
уТКа
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ContentControl вместо наследования?
jupiter,

авторПравильно ли я понял, что визуальное наследование в SilverLight не риализовано и использоваться не должно?
не понятно что вы вкладываете в понятие "визуальное наследование", но кастомные контролы вы можете писать сколь угодные наследуясь от примитивов либо создавая собственные.

касательно остального не понятно что вы хотите сделать.
смотрите в общем исходники контролов которые делают сотрудники Microsoft - Silverlight Toolkit
...
Рейтинг: 0 / 0
16.02.2012, 10:25
    #37664568
Алексей К
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ContentControl вместо наследования?
jupiterЯ поискал инфу, в том числе и на этом форуме. Правильно ли я понял, что визуальное наследование в SilverLight не риализовано и использоваться не должно? И правильно ли я понял, что можно достичь того же результата путем применения ContentControl, в котором нужно реализовать общую функциональность? Вместо наследования применяем агрегацию.Да.

Помимо инкапсуляции через ContentControl можно ещё использовать attached property, Behavior<T> (из Expression Blend SDK), вынос логики во ViewModel и стили. Причём, стили, ViewModel и Behavior<T> можно наследовать.
...
Рейтинг: 0 / 0
16.02.2012, 11:17
    #37664703
SeVa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ContentControl вместо наследования?
В xaml все есть. Помимо UserControl есть еще CustomControl.
Идею простая:
- наследуемся от нужного контрола, добавляем нужные DependencyProperty и обработчики событий или команд
- переопределяем для него template, в нем добавляем нужные визуальные элементы и вызовы обработчиков событий или команд.

Наиболее часто встречаемый вариант - наследник от ContentControl.
Шаблон
Код: xml
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.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
	<ControlTemplate x:Key="CustomControlTemplate" TargetType="CustomControl">
		<Grid Margin="0,8">
			<Grid.ColumnDefinitions>
				<ColumnDefinition Width="*" />
				<ColumnDefinition Width="Auto" />
			</Grid.ColumnDefinitions>
<!-- Обязательно должен быть задан ContentPresenter, чтобы была возможность задавать любой контент для содержимого  -->
			<ContentPresenter x:Name="contentPresenter"
			                  Margin="{TemplateBinding Padding}"
			                  HorizontalAlignment="Stretch"
			                  Content="{TemplateBinding Content}" />
			
<!-- добавляем кнопки и команды -->			
			<toolkit:WrapPanel Grid.Column="1"
			                   Margin="5,0"
			                   HorizontalAlignment="Center"
			                   VerticalAlignment="Center"
			                   Orientation="Horizontal">

				
				<Viewbox Width="10"
					<Button 
					        HorizontalAlignment="Center"
					        VerticalAlignment="Top"
					        Command="{Binding RelativeSource={RelativeSource FindAncestor,
					                                                         AncestorType=ParentControl},
					                          Path=AddItemCommand}"
					        Style="{StaticResource MetroButtonStyle}" />
				</Viewbox>
				<Viewbox Width="10"
					<Button HorizontalAlignment="Right"
					        VerticalAlignment="Center"
					        Command="{Binding RelativeSource={RelativeSource FindAncestor,
					                                                         AncestorType=ParentControl},
					                          Path=DeleteItemCommand}"
					        CommandParameter="{Binding}"
					        Style="{StaticResource MetroButtonStyle}" />
				</Viewbox>
			</toolkit:WrapPanel>
		</Grid>
	</ControlTemplate>

<Style TargetType="CustomControl">
		<Setter Property="Background" Value="Transparent" />
		<Setter Property="Template" Value="{StaticResource CustomControlTemplate}" />
	</Style>



Пример использования
<Controls:CustomControl
Content="Любой контент + кнопки: Добавить; Удалить"
/>
...
Рейтинг: 0 / 0
16.02.2012, 11:18
    #37664706
jupiter
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ContentControl вместо наследования?
авторПомимо инкапсуляции через ContentControl можно ещё использовать attached property, Behavior<T> (из Expression Blend SDK), вынос логики во ViewModel и стили. Причём, стили, ViewModel и Behavior<T> можно наследовать.
Как много путей... Я сейчас вкратце опишу задачу, и посоветуйте мне, пожалуйста, какой именно путь реализации наиболее подходит.

В моем преложении SL есть диаграмма - квадратики, соединенные стрелочками. Квадратики должны иметь возможность менять размер за счет перетаскивания мышью границы. Но квадратики бывают у меня разные - внутри них разное содержимое. Появилась идея следать базовый контрол - квадратик с меняемыми размерами, назовем его ResizableBase (абстрактный класс). У него есть потомки - конкретные классы, которые я буду помещать на диаграмму (один из них - ResizableBorder). Все они унаследуют всойство менять размер. Внутри у каждого свое содержимое.

Вот я и сделал так, но оно не работает:
<UserControl x:Class="MyApp.ResizableBase" .......
потомки:
<MyApp:ResizableBase x:Class="MyApp.ResizableBorder" .....
...
Рейтинг: 0 / 0
16.02.2012, 14:03
    #37665178
jupiter
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ContentControl вместо наследования?
Тогда такой вопрос. Вот я решил сделать свой контрол

Код: xml
1.
<UserControl x:Class="MyApp.ResizableBase" .......


который потом в коде другого контрола можно было бы использовать вот так:

Код: xml
1.
2.
3.
4.
5.
<UserControl x:Class="MyApp.ResizableBorder" ..... 
     <MyApp.ResizableBase  ......>  
               <Другие контролы - врутреннее содержимое>
     </MyApp.ResizableBase>
</UserControl>



Именно в таком виде ругается, что нет свойства Content у класса ResizableBase.
Как это сделать?
Спасибо
...
Рейтинг: 0 / 0
16.02.2012, 16:33
    #37665572
Алексей К
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ContentControl вместо наследования?
jupiterКак много путей...Тут можно так, можно так, надо пробовать. Со стороны трудно сказать как лучше.
jupiterИменно в таком виде ругается, что нет свойства Content у класса ResizableBase.
Как это сделать?1. Отказаться от UserControl. Унаследовать от ContentControl + generic.xaml + стиль + ControlTemplate.

или

2. В UserControl, добавить недостающее свойство. Добавить ContentControl в состав Вашего UserControl и забиндить его на это свойство. Не забыть указать ContentPropertyAttribute.
...
Рейтинг: 0 / 0
16.02.2012, 16:35
    #37665576
Алексей К
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ContentControl вместо наследования?
3. Не делать свой контрол. Использовать имеющийся ContentControl + стиль для него + в стиле нужный Вам ControlTemplate.
...
Рейтинг: 0 / 0
16.02.2012, 21:59
    #37666165
ContentControl вместо наследования?
jupiter,

http://www.codeproject.com/Articles/22952/WPF-Diagram-Designer-Part-1
http://www.codeproject.com/Articles/22952/WPF-Diagram-Designer-Part-2
http://www.codeproject.com/Articles/22952/WPF-Diagram-Designer-Part-3
http://www.codeproject.com/Articles/22952/WPF-Diagram-Designer-Part-4

Отсюда я думаю подчерпнете все что нужно. На основе этих статей я делал дизайнер форм на сильверлайте =)
...
Рейтинг: 0 / 0
17.02.2012, 12:21
    #37666899
jupiter
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ContentControl вместо наследования?
[quot Алексей К]jupiter2. В UserControl, добавить недостающее свойство. Добавить ContentControl в состав Вашего UserControl и забиндить его на это свойство. Не забыть указать ContentPropertyAttribute.
Спасибо. Я почти так и сделал. Вот решение:

Код: xml
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.
31.
32.
33.
34.
35.
<UserControl x:Class="MyApp.ResizableBase"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    SizeChanged="UserControl_SizeChanged"
    DataContext="{Binding RelativeSource={RelativeSource Self}}"
     >
    <Grid>
        <Общие контролы>
        <ContentPresenter Content="{Binding Path=InternalContent}" />
    </Grid>
</UserControl>

<UserControl x:Class="E2EVisualization.ResizableBorder"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    
    >


    <MyApp:ResizableBase>
        <MyApp:ResizableBase.InternalContent>
            <Grid>
                   <Контролы, которые нужны в дочернем классе>
            </Grid>
        </MyApp:ResizableBase.InternalContent>
    </MyApp:ResizableBase>

</UserControl>

    public partial class ResizableBase : UserControl
    {
        /// <summary>
        /// Чтобы присоединитдь внутреннее содержимое к этому родительскому контролу
        /// </summary>
        public UIElement InternalContent { get; set; }
    }




1. Вместо предлагаемого Вами ContentControl у меня ContentPresenter
2. К сложалению, пришлось в коде C# списать свойсово, которое я назвал InternalContent . Нужно подумать, как его объявить декларативно прямо в коде XAML
3. Что за атрибут ContentPropertyAttribute, я пока не разобрался. Но без него тоже работает. Но наверное, это что-то полезное.
4. По поводу создания стиля - притягательная идея, но у меня пока мало опыта и времени. Вопрос: если сдалать дополнительную функциональность, но можно будет реализовать в стиле реакцию на события?

Спасибо.
...
Рейтинг: 0 / 0
17.02.2012, 12:58
    #37667000
SeVa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ContentControl вместо наследования?
jupiter2. К сложалению, пришлось в коде C# списать свойсово, которое я назвал InternalContent . Нужно подумать, как его объявить декларативно прямо в коде XAML


Лучше изучить сначала xaml и не переопределять то, что уже есть.
...
Рейтинг: 0 / 0
17.02.2012, 13:31
    #37667122
jupiter
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ContentControl вместо наследования?
SeVaЛучше изучить сначала xaml и не переопределять то, что уже есть.
Я этим и занимаюсь )) Намекните хотя бы, плиз
...
Рейтинг: 0 / 0
17.02.2012, 13:43
    #37667149
Алексей К
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ContentControl вместо наследования?
jupiter4. По поводу создания стиля - притягательная идея, но у меня пока мало опыта и времени. Вопрос: если сдалать дополнительную функциональность, но можно будет реализовать в стиле реакцию на события?Повторюсь. Обработку событий и прочий дополнительный функционал можно оформить через Attached Property или Behavior<T> . Attached Property можно назначить контролу через стиль. Behavior<T>, к сожалению, назначить через стиль нельзя (а если сильно хочется то можно, но через создание дополнительного attached property :-) ).

Методика работы с присоединяемыми свойствами примерно такая:
Не важно что делает этот код, важен принцип подписки на события
Код: c#
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.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
    public static class TextBoxHelper
    {
        #region IsUpdateBindingSourceEx Property

        public static readonly DependencyProperty IsUpdateBindingSourceExProperty =
            DependencyProperty.RegisterAttached(
                "IsUpdateBindingSourceEx",
                typeof(bool),
                typeof(TextBoxHelper),
                new FrameworkPropertyMetadata(IsUpdateBindingSourceExChanged)
            );

        public static bool GetIsUpdateBindingSourceEx(DependencyObject target)
        {
            return (bool)target.GetValue(IsUpdateBindingSourceExProperty);
        }

        public static void SetIsUpdateBindingSourceEx(DependencyObject target, bool value)
        {
            target.SetValue(IsUpdateBindingSourceExProperty, value);
        }

        static void IsUpdateBindingSourceExChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var textBox = (TextBox)sender;
            var oldValue = (bool)e.OldValue;
            var newValue = (bool)e.NewValue;

            if (oldValue)
                textBox.KeyDown -= textBox_EnterKeyDown;

            if (newValue)
                textBox.KeyDown += textBox_EnterKeyDown;
        }

        static void textBox_EnterKeyDown(object sender, KeyEventArgs e)
        {
            var textBox = (TextBox)sender;

            if
            (
                KeyGestures.Enter.Matches(e) &&
                textBox.IsReadOnly == false &&
                textBox.AcceptsReturn == false &&
                VisualTreeHelperEx.GetParents(textBox).OfType<DataGrid>().Any() == false
            )
            {
                BindingHelper.UpdateTextBoxSource(textBox);
                e.Handled = true;
            }
        }
 
        #endregion
    }


ЗЫ: Про Behavior<T> смотрите в документации про Expression Blend SDK
...
Рейтинг: 0 / 0
17.02.2012, 14:12
    #37667224
SeVa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ContentControl вместо наследования?
jupiterSeVaЛучше изучить сначала xaml и не переопределять то, что уже есть.
Я этим и занимаюсь )) Намекните хотя бы, плиз

Я уже намекнул в первом посте
...
Рейтинг: 0 / 0
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / ContentControl вместо наследования? / 14 сообщений из 14, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]