Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > WPF и Silverlight > Редактирование через ХАМЛ внутнренних элементов Us


Автор: SeregaS 28.3.2009, 18:30
Редактирование через ХАМЛ внутнренних элементов UserControlа

У элемента управления достаточно сделать публичными свойства что бы они доступны в ХАМЛ
все прекрасно когда  (число или строка) не обязательно даже пользоваться DependencyProperty
,но при попытке сделать доступным целиком  элемент   например ListBox

      
Код

  public ListBox listBox
        {
            get { return (decimal)GetValue(listBoxProperty); }
            set { SetValue(listBoxProperty, value); }
        }
       
        public static readonly DependencyProperty listBoxProperty =
            DependencyProperty.Register("listBox", typeof(ListBox), typeof(UserControl1), null);




Код

<UserControl x:Class="Test_rTableWindow.UserControl1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="300" Width="300">

        <ListBox  Margin="81,140,99,60" Name="listBox1" />

</UserControl>



использовать его не получается, так как я не могу обратиться к items из Хамла, можно конечно items листБокса 
то же сделать публичными, но как то не красиво это, да и все свойства весьма сложно перебрать 
 возможно есть какой то другой более красивый способ ?

Автор: Partizan 28.3.2009, 19:30
SeregaS, какая первоначальная задача? что надо сделать с коллекцией из xaml?

Автор: SeregaS 28.3.2009, 20:02
задача создать контрол содержащий внутренние контролы
и внутренние элементы нужно настраивать из хамла 
как у  элементов у микрософт 
ну например дата грид/ у него есть много элементов и к ним свободно можно обращаться из хамла

может конечно использовать не UserControl ,  а наследовать от Controla
и попробовать создать свой элемент с нуля

но так задача кажется еще более сложной  

Автор: -Mikle- 28.3.2009, 22:35
Цитата(SeregaS @  28.3.2009,  23:02 Найти цитируемый пост)
внутренние элементы нужно настраивать из хамла 
как у  элементов у микрософт 

Я не видел нигде, чтоб было так, как вы говорите.

Цитата(SeregaS @  28.3.2009,  23:02 Найти цитируемый пост)
ну например дата грид/ у него есть много элементов и к ним свободно можно обращаться из хамла

К каким элементам можно обращаться? О чем вы? Вы обращаетесь не более чем к свойствам контрола.

Вот вам начало, с чего начать копать:
Код

<UserControl x:Class="WpfApplication1.UserControl1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <ListBox Name="listBox" />
    </Grid>
</UserControl>


Код

    public class ButtonCollection : ObservableCollection<Button> { }

    public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();
            this.Buttons = new ButtonCollection();
        }

        ButtonCollection _buttons;
        public ButtonCollection Buttons
        {
            get { return _buttons; }
            set
            {
                _buttons = value;
                listBox.ItemsSource = _buttons;
            }
        }
    }


А вот вариант с DependencyProperty
Код

    public class ButtonCollection : ObservableCollection<Button>
    {
        public static readonly ButtonCollection Empty = new ButtonCollection();
    }

    public partial class UserControl1 : UserControl
    {
        public static DependencyProperty ButtonsProperty = DependencyProperty.Register("Buttons", typeof(ButtonCollection), typeof(UserControl1), new PropertyMetadata(ButtonCollection.Empty, OnButtonsPropertyChanged));
        private static void OnButtonsPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            ((UserControl1)o).listBox.ItemsSource = (ButtonCollection)e.NewValue;
        }

        public UserControl1()
        {
            InitializeComponent();
            this.Buttons = new ButtonCollection();
        }

        public ButtonCollection Buttons
        {
            get
            {
                return (ButtonCollection)this.GetValue(ButtonsProperty);
            }
            set
            {
                this.SetValue(ButtonsProperty, value);
            }
        }
    }


Используются так:
Код

        <l:UserControl1>
            <l:UserControl1.Buttons>
                <Button>Hello</Button>
                <Button>World</Button>
                <Button>!!!</Button>                
            </l:UserControl1.Buttons>
        </l:UserControl1>

Автор: SeregaS 29.3.2009, 10:11

Спасибо пример интересный  очень близко к тому что я искал

Ну а на счет того к чему я обращаюсь к самому контролу или к его свойствам, оно  как бы без разницы 
если я могу в в дата гриде настороить вид колонки, то что это как не обращение к колонке
так же и в вашем примере я обращаюсь к кнопкам и настраиваю их как хочу 

Автор: -Mikle- 29.3.2009, 11:56
Цитата(SeregaS @  29.3.2009,  13:11 Найти цитируемый пост)
очень близко к тому что я искал

А нужно что-то другое?

Автор: SeregaS 29.3.2009, 13:03
скорее всего да не совсем подходит хотя я сейчас эксперементирую
суть такая 
есть элемент (1) производный от DataGrid, он  работает, имеет свои  контекстстные  меню и все такое 

 надо к на этой основе создать элемент (2) В Который добавить ToolBar и статус бар. 

при этом пожелания наших идеологов что бы этот новый элемент настраивался точно так же как (1)
по умолчанию определенные пункты контектсного меню отображались в ToolBarе
и  при желании нужно добавлять пункты меню в  ToolBar
то же и со статус баром.


Автор: xxxSeVa 31.3.2009, 13:44
Не стоит городить таких монстров.Это должны быть отдельные контролы.

Автор: -Mikle- 31.3.2009, 15:54
Цитата(SeregaS @  29.3.2009,  16:03 Найти цитируемый пост)
при этом пожелания наших идеологов 

Видимо эти идеологи совсем не знают, что такое XAML...
Нельзя задать свойство объекта на который ссылается другое свойство.
Вот так не получится сделать
Код

<Canvas>
    <Canvas.RenderTransform.X>
        30
    </Canvas.RenderTransform.X>
</Canvas>

Автор: xxxSeVa 31.3.2009, 18:14
Более приемлемый вариант я описал в обсуждении GUI.
Возможен еще один вариант через Attached Behavior

Код

public class SelectionBehavior
{
    public static DependencyProperty SelectionChangedProperty =
            DependencyProperty.RegisterAttached("SelectionChanged",
            typeof(ICommand),
            typeof(SelectionBehavior),
            new UIPropertyMetadata(SelectionBehavior.SelectedItemChanged));
    public static void SetSelectionChanged(DependencyObject target, ICommand value)
    {
        target.SetValue(SelectionBehavior.SelectionChangedProperty, value);
    }
    private static void SelectedItemChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
    {
        Selector element = target as Selector;
        if (element == null) throw new InvalidOperationException("This behavior can be attached to Selector item only.");
        if ((e.NewValue != null) && (e.OldValue == null))
        {
            element.SelectionChanged += SelectionChanged;
        }
        else if ((e.NewValue == null) && (e.OldValue != null))
        {
            element.SelectionChanged -= SelectionChanged;
        }
    }
    private static void SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
    {
        UIElement element = (UIElement)sender;
        ICommand command = (ICommand)element.GetValue(SelectionBehavior.SelectionChangedProperty);
        command.Execute(((Selector) sender).SelectedValue);
    }
}

<ListBox local:SelectionBehavior.SelectionChanged="{Binding MyCommand}"  
              ItemsSource="{Binding MyViewModel.Commands}"
              Name="MyComboBox"/> 


MyViewModel.Commands -  список команд
MyCommand - DelegateCommand из CompositeWPF

Автор: SeregaS 1.4.2009, 09:16
проблемма решена довольно просто в шаблон элемента введены дополнительные элементы со своими именами
но !!! 
Код

 public override void OnApplyTemplate()
 
{
            base.OnApplyTemplate();     //      PART_ToolBar
         ToolBar   TB = this.Template.FindName("PART_ToolBar", this) as ToolBar;
}


не находит ничего 

Код

static public ToolBar GetToolBar(DependencyObject x,string Name)
      {

          ToolBar tb = null;
          tb = x as ToolBar;
          if (tb != null) { return tb; }
          tb = (ToolBar)LogicalTreeHelper.FindLogicalNode(x, Name);
          if (tb != null) { return tb; }
          int xx = VisualTreeHelper.GetChildrenCount(x);
          for (int i = 0; i < xx; i++)
          {
              DependencyObject obj = VisualTreeHelper.GetChild(x, i);

              tb = (ToolBar)LogicalTreeHelper.FindLogicalNode(obj, Name);
              if (tb != null) { return tb; }

              tb = obj as ToolBar;
              if (tb != null) { return tb; }
              tb = GetToolBar(obj,Name) as ToolBar;
              if (tb != null) { return tb; }
          }
          return tb;
      }

а вот эта функция находит правда не сразу а через 0.1 секунду после OnApplyTemplate()
  
Код
      
  System.Windows.Forms.Timer TM = new System.Windows.Forms.Timer();
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();     //      PART_ToolBar
         ToolBar   TB = this.Template.FindName("PART_ToolBar", this) as ToolBar;
           if (TB != null) { this._MenuItems.AddToolBarItems(TB); }

            TM.Interval = 100;
           TM.Tick += new EventHandler(TM_Tick);
           TM.Start();
        }

   
   void TM_Tick(object sender, EventArgs e)
        {
               
         ToolBar   TBf = this.Template.FindName("PART_ToolBar", this) as ToolBar;
             //по прежнему ни чего не находит TBf==null
            TM.Stop();
            _ToolBar = Helper.GetToolBar(this, "PART_ToolBar");
            //а вот сейчас не нулл ;)
}


и где здесь собака зарыта???

Добавлено через 5 минут и 6 секунд
да инетервал можно ставить хоть 1 все равно рабоатет

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)