none
Написать контроллер. C#, Silverlight RRS feed

  • Вопрос

  • Народ хай,

    Подскажите как написать контроллер собственный? Какой алгоритм и т.д. Может пример какой есть с комментами?


    • Изменено Z.Zidane 26 апреля 2012 г. 8:22
    26 апреля 2012 г. 7:51

Ответы

  • Хм, если вам нужен множественный выбор, то это не RadioButton а CheckBox. Если вам нужно, чтобы Checkbox выглядел как RadioButton, то используйте Template (см. пост выше).

    Ну или совсем изврат:

    <RadioButton Content="первый" GroupName="g1" Click="RadioButton_Click_1" />
    <RadioButton Content="второй" GroupName="g2" Click="RadioButton_Click_1" />
    <RadioButton Content="третий" GroupName="g3" Click="RadioButton_Click_1"  />
    <RadioButton Content="четвертый" GroupName="g4" Click="RadioButton_Click_1" />

    Обработчик:

    private void RadioButton_Click_1(object sender, RoutedEventArgs e)
    {
        RadioButton rb = sender as RadioButton;
        if (rb != null && rb.IsChecked.Value)
        {
            if (rb.Tag != null)
            {
                rb.IsChecked = false;
            }
            else
            {
                rb.Tag = 1;
            }
        }
    }

    Внешний вид:

    • Помечено в качестве ответа Z.Zidane 27 апреля 2012 г. 10:54
    26 апреля 2012 г. 11:51
    Отвечающий
  • Добавляете в проект новый UserControl.

    В его XAML разметке Grid заменяете на StackPanel:

    <StackPanel x:Name="spMain">
        <RadioButton Content="первый" GroupName="g1" Click="RadioButton_Click_1" />
        <RadioButton Content="второй" GroupName="g2" Click="RadioButton_Click_1" />
        <RadioButton Content="третий" GroupName="g3" Click="RadioButton_Click_1"  />
        <RadioButton Content="четвертый" GroupName="g4" Click="RadioButton_Click_1" />
    </StackPanel>

    В код добавляете:

    public bool[] CheckedItem = new bool[4];
    
    private void RadioButton_Click_1(object sender, RoutedEventArgs e)
    {
        RadioButton rb = sender as RadioButton;
        if (rb != null && rb.IsChecked.Value)
        {
            if (rb.Tag != null)
            {
                rb.IsChecked = false;
            }
            else
            {
                rb.Tag = 1;            
            }
            CheckedItem[spMain.Children.IndexOf(rb)] = rb.IsChecked.Value;
        }
    }

    Из внешнего мира можете посмотреть какие выбраны поля через свойство CheckedItem.

    Этот UserControl кидаете везде, где вам нужен данный функционал.

    • Предложено в качестве ответа Алексей ЛосевEditor 26 апреля 2012 г. 16:05
    • Помечено в качестве ответа Z.Zidane 27 апреля 2012 г. 10:54
    26 апреля 2012 г. 12:13
    Отвечающий
  • Мой пример с UserControl вас устроил всем? Ну кроме динамичности? Если да, то перечень куда копать:

    1. В XAML файле у контрола удалите все содержимое StackPanel.

    2. В cs файле добавьте Dependency Property с именем Items и типом string[] или List<string>.

    3. Подпишите обработчик на изменение этого свойства (для этого посмотрите перегруженные конструкторы класса PropertyMetadata).

    4. В обработчике данного метода реализуйте:

    а) Очистку поля Children у spMain.

    б) Цикл, который перебирает свойство Items и для каждого элемента массива создает RadioButton.

    в) Для свежесозданного компонента настраиваем свойства Content, GroupName (см. как было в XAML) и не забываем подписаться на событие Click нашим методом RadioButton_Click_1.

    г) Добавляем RadioButton в коллекцию Children нашего spMain.

    5. В свойство CheckedItem записываем массив размер которого равен размеру массива Items.

    Да, в начало не забьываем добавить проверку, что Items у нас не null. Ну это уже мелочи.

    Для использования нашего контрола, достаточно будет разместить его в XAML и присвоить ему из кода или через Binding свойство Items.

    • Предложено в качестве ответа Алексей ЛосевEditor 26 апреля 2012 г. 16:05
    • Помечено в качестве ответа Z.Zidane 27 апреля 2012 г. 10:53
    26 апреля 2012 г. 16:04
    Отвечающий

Все ответы

  • This is Russian forum, please ask your question in Russian or ask your question in English Forum. Thank you.
    26 апреля 2012 г. 8:17
    Модератор
  • Hi.

    Ну вот, а я на английском начал ответ писать...

    Ладно, давайте на русском.

    1. Создаете новый класс:

    public class MyControl : Control
    {
        public string MyText
        {
            get { return (string)GetValue(MyTextProperty); }
            set { SetValue(MyTextProperty, value); }
        }
    
        // Using a DependencyProperty as the backing store for MyText.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MyTextProperty =
            DependencyProperty.Register("MyText", typeof(string), typeof(MyControl), new PropertyMetadata(""));
    }

    2. Кидаете новый контрол на форму (если проведете билд, то прям из toolbox можно):

    <local:MyControl MyText="Hello!" HorizontalAlignment="Left" Height="100" Margin="102,142,0,0" VerticalAlignment="Top" Width="100"/>

    3. Добавляете стиль, который заменит у вашего компонента внешний вид (Template):

    <UserControl.Resources>
        <Style TargetType="local:MyControl">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate>
                        <Grid>
                            <TextBlock Text="{Binding  MyText, RelativeSource={RelativeSource Mode=TemplatedParent}}" />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </UserControl.Resources>

    Запускаете и видите на месте своего компонента Hello!

    Если есть вопросы, или нужны исходники примера пишите. отвечу, выложу.

    • Предложено в качестве ответа Alexandr Gashper 26 апреля 2012 г. 8:43
    26 апреля 2012 г. 8:26
    Отвечающий
  • Попробую разобрать Ваш код. А мы наследуем же от Control. А если наследовать от UIElement? В чем принципиальная разница? Суть в том, что я хочу сделать радиобаттон, у которого можно выбрать несколько значений, а не одно.
    26 апреля 2012 г. 8:39
  • Я не понимаю, чем вас не устраивает Control, который является потомком UIElement. Можете объяснить чуть более подробно?

    Кстати, я бы для решения вашей задачи, взял еще более уточненного потомка: ButtonBase или ToggleButton. Если, кстати, посмотрите на его иерархию наследования, то увидите там и Control и UIElement. Просто чем более уточненный класс вы будите использовать, тем меньше вам кода придется писать самому.

    Можете при написании нового компонента еще вот на эту картинку смотреть, для выбора наиболее близкого родственника:


    26 апреля 2012 г. 8:54
    Отвечающий
  • Попробую разобрать Ваш код. А мы наследуем же от Control. А если наследовать от UIElement? В чем принципиальная разница? Суть в том, что я хочу сделать радиобаттон, у которого можно выбрать несколько значений, а не одно.

    Тогда вам нужно наследоваться от UserControl, создавайте свой контрол с помощью Project - New Item - Silverlight User Control. Потом переносите/пишите нужную xaml разметку и в код добавляете нужные методы или свойства. А дальше как сказали выше, располагаете на главной страницу этот контрол и используете.

    Все эти элементы UIElement, Control, и UserControl находятся в одной иерархии, но каждый следующий привносит новые свойства и расширяет возможности предыдущих.

    System.Object 
      System.Windows.Threading.DispatcherObject
        System.Windows.DependencyObject
          System.Windows.Media.Visual
            System.Windows.UIElement
              System.Windows.FrameworkElement
                System.Windows.Controls.Control
                  System.Windows.Controls.ContentControl
                    System.Windows.Controls.UserControl


    Для связи [mail]


    26 апреля 2012 г. 8:58
    Модератор
  • ту Алексей, да устраивает всем, просто не знаю что лучше юзать, теперь вроде ясно. Ну тогда уж ToggleButton наверн лучше, если по схеме.

    После создания св-ва, честно говоря не знаю какие дальше методы нужны для решения этой задачи.

    ту Дмитрий, нужно попробовать

    26 апреля 2012 г. 9:10
  • Алексей, если можете. то поделитесь исходниками, может по ним смогу решить свою задачу
    26 апреля 2012 г. 9:37
  • Могу. Но у меня для вас две плохих новости.

    1. Я использую Visual Studuo 11 и не знаю как у вас откроется проект. Вполне вероятно придется по файлам подключать в другой проект.

    2. Пока у меня был обед, я уже написал Checkbox с 3 состояниями. А удалять код, чтобы вам выслать первый вариант мне уже лень.

    Если эти две новости вас не очень печалят, то вот.

    26 апреля 2012 г. 9:59
    Отвечающий
  • Спасибо за код, открылся частично, MyControlExampleSL.Web - недоступен. Вы имели ввиду наверно RadioBUtton, а не checkbox?
    26 апреля 2012 г. 10:44
  • Ну чтобы у них поведение было как у RadioButton, они должны друг с другом взаимодействовать. А сейчас они каждый сам за себя.

    26 апреля 2012 г. 10:48
    Отвечающий
  • Сорри за кривизну, вот примерно так надо, чтобы было реал выбрать несколько

    26 апреля 2012 г. 10:55
  • Не очень понял вопрос. Сейчас при помощи моего компонента (называйте его как хотите), вы можете:

    1. Разместить их кучу на форме (как у вас на картинке 4 тоже можно).

    2. В любом из них выбрать любое состояние. Например в первос состоятие 1, во втором состояние 2, в третьем состояние 3, в четвертом состояние 2.

    3. Cчитать, в каком состоянии какой из компонентов.

    Если вам не нравиться внешний вид моего компонента, то как пользоваться Template можно почитать на msdn или вот здесь с небольшими моими комментариями.


    26 апреля 2012 г. 11:10
    Отвечающий
  • Видимо я не понимаю что-то. У Вас в проекте при запуске -  кнопки, 
    кот. меняют значения, а я хотел сделать панель и в ней разместить радиобаттоны и иметь возможность выбрать скажем 1-ый и второй (по дефолту же радиобаттоны позволяют только одно значение выбрать)
    • Изменено Z.Zidane 26 апреля 2012 г. 11:25
    26 апреля 2012 г. 11:23
  • Хм, если вам нужен множественный выбор, то это не RadioButton а CheckBox. Если вам нужно, чтобы Checkbox выглядел как RadioButton, то используйте Template (см. пост выше).

    Ну или совсем изврат:

    <RadioButton Content="первый" GroupName="g1" Click="RadioButton_Click_1" />
    <RadioButton Content="второй" GroupName="g2" Click="RadioButton_Click_1" />
    <RadioButton Content="третий" GroupName="g3" Click="RadioButton_Click_1"  />
    <RadioButton Content="четвертый" GroupName="g4" Click="RadioButton_Click_1" />

    Обработчик:

    private void RadioButton_Click_1(object sender, RoutedEventArgs e)
    {
        RadioButton rb = sender as RadioButton;
        if (rb != null && rb.IsChecked.Value)
        {
            if (rb.Tag != null)
            {
                rb.IsChecked = false;
            }
            else
            {
                rb.Tag = 1;
            }
        }
    }

    Внешний вид:

    • Помечено в качестве ответа Z.Zidane 27 апреля 2012 г. 10:54
    26 апреля 2012 г. 11:51
    Отвечающий
  • "Если вам нужно, чтобы Checkbox выглядел как RadioButton" - вот это и нужно, только нужо сделать свой контроллер и чтобы кнопки были как в одной панели, а нк по отдельности
    26 апреля 2012 г. 12:04
  • Добавляете в проект новый UserControl.

    В его XAML разметке Grid заменяете на StackPanel:

    <StackPanel x:Name="spMain">
        <RadioButton Content="первый" GroupName="g1" Click="RadioButton_Click_1" />
        <RadioButton Content="второй" GroupName="g2" Click="RadioButton_Click_1" />
        <RadioButton Content="третий" GroupName="g3" Click="RadioButton_Click_1"  />
        <RadioButton Content="четвертый" GroupName="g4" Click="RadioButton_Click_1" />
    </StackPanel>

    В код добавляете:

    public bool[] CheckedItem = new bool[4];
    
    private void RadioButton_Click_1(object sender, RoutedEventArgs e)
    {
        RadioButton rb = sender as RadioButton;
        if (rb != null && rb.IsChecked.Value)
        {
            if (rb.Tag != null)
            {
                rb.IsChecked = false;
            }
            else
            {
                rb.Tag = 1;            
            }
            CheckedItem[spMain.Children.IndexOf(rb)] = rb.IsChecked.Value;
        }
    }

    Из внешнего мира можете посмотреть какие выбраны поля через свойство CheckedItem.

    Этот UserControl кидаете везде, где вам нужен данный функционал.

    • Предложено в качестве ответа Алексей ЛосевEditor 26 апреля 2012 г. 16:05
    • Помечено в качестве ответа Z.Zidane 27 апреля 2012 г. 10:54
    26 апреля 2012 г. 12:13
    Отвечающий
  • проблема в том, что радиобаттоны должны создаваться динамически
    26 апреля 2012 г. 13:27
  • Как то странно вы вопросы задаете. Давайте я за вас задам:

    ---

    Необходимо разработать контрол, в свойство которого можно передать массив строк, на основе которых в компоненте должны сгенерироваться элементы для выбора значений. Элементы для выбора должны выглядеть как RadioButton, а поведение обеспечивать как CheckBox. Также у компонента должно быть поле типа массив булевых значений, в котором можно посмотреть какие из компонентов выбора отмечены пользователем.

    Подскажите, что мне надо почитать, с чем ознакомиться, чтобы написать такой компонент?

    ---

    Я правильно изложил вашу проблему?

    26 апреля 2012 г. 14:04
    Отвечающий
  • Примерно так, да. Теперь можете и ответить на свой вопрос :)
    , точнее на мой, но в Вашем исполнении
    • Изменено Z.Zidane 26 апреля 2012 г. 14:22
    26 апреля 2012 г. 14:21
  • Мой пример с UserControl вас устроил всем? Ну кроме динамичности? Если да, то перечень куда копать:

    1. В XAML файле у контрола удалите все содержимое StackPanel.

    2. В cs файле добавьте Dependency Property с именем Items и типом string[] или List<string>.

    3. Подпишите обработчик на изменение этого свойства (для этого посмотрите перегруженные конструкторы класса PropertyMetadata).

    4. В обработчике данного метода реализуйте:

    а) Очистку поля Children у spMain.

    б) Цикл, который перебирает свойство Items и для каждого элемента массива создает RadioButton.

    в) Для свежесозданного компонента настраиваем свойства Content, GroupName (см. как было в XAML) и не забываем подписаться на событие Click нашим методом RadioButton_Click_1.

    г) Добавляем RadioButton в коллекцию Children нашего spMain.

    5. В свойство CheckedItem записываем массив размер которого равен размеру массива Items.

    Да, в начало не забьываем добавить проверку, что Items у нас не null. Ну это уже мелочи.

    Для использования нашего контрола, достаточно будет разместить его в XAML и присвоить ему из кода или через Binding свойство Items.

    • Предложено в качестве ответа Алексей ЛосевEditor 26 апреля 2012 г. 16:05
    • Помечено в качестве ответа Z.Zidane 27 апреля 2012 г. 10:53
    26 апреля 2012 г. 16:04
    Отвечающий
  • Z.Zidane, не забудьте отметить сообщение или сообщения, которые содержат решение вашей проблемы (кнопка "Пометить как ответ" под каждым сообщением).

    Спасибо.


    Для связи [mail]

    27 апреля 2012 г. 6:44
    Модератор
  • вообщем буду пробовать, спасибо
    27 апреля 2012 г. 10:54