WPF DataContext ... ищет простейший синтаксис - PullRequest
2 голосов
/ 09 сентября 2010

В следующем XAML UserControl я связываю несколько элементов со свойствами в связанном классе UserControl.

<UserControl x:Class="Kiosk.EventSelectButton"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Kiosk"
    Height="130" Width="130">
    <Grid>
        <Button 
            Style="{DynamicResource DarkButton130x130}" 
            HorizontalAlignment="Left" 
            VerticalAlignment="Center">
            <Grid Margin="0,0,0,0" Height="118" Width="118">
                <Image VerticalAlignment="Top" HorizontalAlignment="Center" Source="image/select_button_arrows.png" />
                <Image x:Name="EventImageComponent" VerticalAlignment="Center" HorizontalAlignment="Center" Effect="{DynamicResource KioskStandardDropShadow}" Source="{Binding Path=EventImage}" />
                <TextBlock x:Name="SelectTextBlock" Text="{Binding Path=SelectText}" VerticalAlignment="Top" HorizontalAlignment="Center" Margin="0,-2,0,0" FontSize="10pt" Foreground="#5aaff5" />
                <TextBlock x:Name="LabelTextBlock" VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="0,0,0,0" FontSize="14pt" FontWeight="Bold" Text="{Binding Path=Label}"/>
            </Grid>
        </Button>
    </Grid>
</UserControl>

В contstructor связанного класса я применяю DataContext элементов к этому , как вы можете видеть ниже.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Kiosk
{
    /// <summary>
    /// Interaction logic for EventSelectButton.xaml
    /// </summary>
    public partial class EventSelectButton : UserControl
    {

        public String ValueContainer;

        private String _EventImage;

        public String EventImage
        {
            get
            {
                return _EventImage;
            }
            set
            {
                _EventImage = value;
            }
        }

        private String _Label;

        public String Label
        {
            get
            {
                return _Label;
            }
            set
            {
                _Label = value;
            }
        }

        private String _SelectText;

        public String SelectText 
        {
            get 
            { 
                return _SelectText; 
            }
            set 
            { 
                _SelectText = value; 
            }
        }

        public EventSelectButton()
        {
            InitializeComponent();
            LabelTextBlock.DataContext = this;
            SelectTextBlock.DataContext = this;
            EventImageComponent.DataContext = this;
        }
    }
}

Редактировать

Хотя это работает как задумано, мне интересно знать, есть ли более простой способ сделать это. ( edit, извлеченные уроки. ) Это на самом деле не будет работать после инициализации, общие свойства будут установлены, однако, поскольку класс не использует DependentProperties или, наоборот, реализует INotifyPropertyChanged, привязка не будет работать ожидается. ( конец редактирования )

Например,

  • Могу ли я установить для DataContext этих элементов в XAML значение , это (как экземпляр EventSelectButton), и если да, то как?
  • В качестве альтернативы возможно ли наследовать DataContext от родительского элемента UserControl, что упрощает пути привязки.

Единственные альтернативы, которые я нашел до сих пор, являются более многословными, например с помощью метода привязки RelativeSource для поиска предка EventSelectButton.

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

1 Ответ

2 голосов
/ 09 сентября 2010

Один из способов сделать следующее:

  1. Назовите свой UserControl в XAML.
  2. Свяжите DataContext корневого элемента (т.е. Grid) с UserControl.

Как это:

<UserControl x:Name="uc">
  <Grid DataContext="{Binding ElementName=uc}">
  .
  .
  .
  </Grid>
</UserControl>

Теперь вы спросите, почему бы просто не установить DataContext самого UserControl? Что ж, это просто гарантирует, что установка DataContext экземпляра UserControl будет по-прежнему работать без влияния на привязки в визуальном дереве UserControl. Поэтому что-то вроде приведенного ниже будет работать нормально.

<Window>
  <uc:EventSelectButton DataContext="{Binding SomeDataContext}" Width="{Binding SomeDataContextWidth}"/>
</Window>

РЕДАКТИРОВАТЬ

Для завершения решения необходимо изменить свойства в UserControl, чтобы вместо этого использовать объекты DependencyProperty. Ниже приведены обновления кодов:

XAML:

<UserControl x:Class="Kiosk.EventSelectButton"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Kiosk"
    x:Name="root"             
    Height="130" Width="130">
    <Grid x:Name="LayoutRoot" DataContext="{Binding ElementName=root}">
        <Button 
            Style="{DynamicResource DarkButton130x130}" 
            HorizontalAlignment="Left" 
            VerticalAlignment="Center">
            <Grid Margin="0,0,0,0" Height="118" Width="118" >
                <Image VerticalAlignment="Top" HorizontalAlignment="Center" Source="image/select_button_arrows.png" />
                <Image Source="{Binding EventImage}" VerticalAlignment="Center" HorizontalAlignment="Center" Effect="{DynamicResource KioskStandardDropShadow}"  />
                <TextBlock Text="{Binding SelectText}" VerticalAlignment="Top" HorizontalAlignment="Center" Margin="0,-2,0,0" FontSize="10pt" Foreground="#5aaff5" />
                <TextBlock Text="{Binding Label}" VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="0,0,0,0" FontSize="14pt" FontWeight="Bold" />
            </Grid>
        </Button>
    </Grid>
</UserControl>

Code-Behind:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Kiosk
{
    public partial class EventSelectButton : UserControl
    {
        public static readonly DependencyProperty EventImageProperty =
                DependencyProperty.Register(
                "EventImage",
                typeof(string),
                typeof(EventSelectButton));

        public String EventImage
        {
            get { return (string)GetValue(EventImageProperty); }
            set { SetValue(EventImageProperty, value); }
        }

        public static readonly DependencyProperty SelectTextProperty =
                DependencyProperty.Register(
                "SelectText",
                typeof(string),
                typeof(EventSelectButton));

        public String SelectText
        {
            get { return (string)GetValue(SelectTextProperty); }
            set { SetValue(SelectTextProperty, value); }
        }

        public static readonly DependencyProperty LabelProperty =
                DependencyProperty.Register(
                "Label",
                typeof(string),
                typeof(EventSelectButton));

        public String Label
        {
            get { return (string)GetValue(LabelProperty); }
            set { SetValue(LabelProperty, value); }
        }

        public EventSelectButton()
        {
            InitializeComponent();
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...