RequirementПОЗВОЛЯЮЩ имени элементы в нескольких содержимого пользовательского элемента управления
Давайте начнем с того, что я пытаюсь достичь. Я хочу иметь сетку с двумя столбцами и разделителем сетки (для этого есть немного больше, но, давайте сделаем это простым). Я хочу иметь возможность использовать эту сетку в разных местах, поэтому вместо того, чтобы создавать ее каждый раз, я хочу создать настраиваемый элемент управления, который содержит два ContentPresenters
.
Конечной целью является эффективным, чтобы иметь возможность написать XAML как это:
<MyControls:MyGrid>
<MyControls:MyGrid.Left>
<Label x:Name="MyLabel">Something unimportant</Label>
</MyControls:MyGrid.Left>
<MyControls:MyGrid.Right>
<Label>Whatever</Label>
</MyControls:MyGrid.Right>
</MyControls:MyGrid>
ВАЖНО: Обратите внимание на то, что я хочу, чтобы применить Name
к моему Label
элементу.
Покушение 1
Я сделал много поиска решений, и лучший способ я нашел, чтобы создать UserControl
вместе с XAML файл, который определил мою сетку. Этот файл XAML содержал элементы 2 ContentPresenter
, и с магией привязки я смог получить что-то хорошее, что было здорово. Однако проблема с этим подходом не будучи в состоянии Name
вложенных элементы управления, что приводит к следующей ошибке сборки:
Cannot set Name attribute value 'MyName' on element 'MyGrid'. 'MyGrid' is under the scope of element 'MyControls', which already had a name registered when it was defined in another scope.
С этой ошибкой в руке, я вернулся к доктору Google ...
Покушение 2 (ток)
После намного больше поисков я нашел некоторую информацию здесь, так что предложила эту проблему была из-за наличия связанного XAML файл с MyGrid
классом, и эта проблема должна быть разрешима путем удаления XAML и создание всех управления через код в методе OnInitialized
.
Итак, я отправился по этому пути и получил все кодирование и компиляцию. Хорошей новостью является то, что теперь я могу добавить Name
в свой вложенный Label
элемент управления, плохая новость ничего не делает! Не в режиме разработки, а не при запуске приложения. Ошибок не возникает.
Итак, мой вопрос: что мне не хватает? Что я делаю не так?
Я также открыт для предложений по другим способам удовлетворения моих требований.
Текущий код
public class MyGrid : UserControl
{
public static readonly DependencyProperty LeftProperty = DependencyProperty.Register("Left", typeof(object), typeof(MyGrid), new PropertyMetadata(null));
public object Left
{
get { return (object)GetValue(LeftProperty); }
set { SetValue(LeftProperty, value); }
}
public static readonly DependencyProperty RightProperty = DependencyProperty.Register("Right", typeof(object), typeof(MyGrid), new PropertyMetadata(null));
public object Right
{
get { return (object)GetValue(RightProperty); }
set { SetValue(RightProperty, value); }
}
Grid MainGrid;
static MyGrid()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MyGrid), new FrameworkPropertyMetadata(typeof(MyGrid)));
}
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
//Create control elements
MainGrid = new Grid();
//add column definitions
ColumnDefinition leftColumn = new ColumnDefinition()
{
Name = "LeftColumn",
Width = new GridLength(300)
};
MainGrid.ColumnDefinitions.Add(leftColumn);
MainGrid.ColumnDefinitions.Add(new ColumnDefinition()
{
Width = GridLength.Auto
});
//add grids and splitter
Grid leftGrid = new Grid();
Grid.SetColumn(leftGrid, 0);
MainGrid.Children.Add(leftGrid);
GridSplitter splitter = new GridSplitter()
{
Name = "Splitter",
Width = 5,
BorderBrush = new SolidColorBrush(Color.FromArgb(255, 170, 170, 170)),
BorderThickness = new Thickness(1, 0, 1, 0)
};
MainGrid.Children.Add(splitter);
Grid rightGrid = new Grid();
Grid.SetColumn(rightGrid, 1);
MainGrid.Children.Add(rightGrid);
//add content presenters
ContentPresenter leftContent = new ContentPresenter();
leftContent.SetBinding(ContentPresenter.ContentProperty, new Binding("Left") { Source = this });
leftGrid.Children.Add(leftContent);
ContentPresenter rightContent = new ContentPresenter();
rightContent.SetBinding(ContentPresenter.ContentProperty, new Binding("Right") { Source = this });
rightGrid.Children.Add(rightContent);
//Set this content of this user control
this.Content = MainGrid;
}
}
'создавая все управление через код' - Неправильно. Это то, для чего нужны 'ControlTemplate'. –
@HighCore: Спасибо за ваш полезный комментарий ... вы говорите, что у вас есть предложение заменить вторую попытку? – musefan
Вы должны переключить реализацию с 'UserControl' на' CustomControl' и не должно быть проблем с именем. –