#mvvm #windows-phone
#mvvm #windows-phone
Вопрос:
У меня есть следующий простой пользовательский элемент управления, который я определил для приложения Windows Phone. XAML для элемента управления выглядит следующим образом :
<UserControl x:Class="PhoneApp1.MyControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="480"
d:DesignWidth="480"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid x:Name="LayoutRoot">
<TextBlock Text="{Binding MyLabel}" />
</Grid>
Кроме того, пользовательский элемент управления имеет свойство зависимости, которое выглядит следующим образом :
public partial class MyControl : UserControl
{
public MyControl()
{
InitializeComponent();
}
public static readonly DependencyProperty MyLabelProperty =
DependencyProperty.Register("MyLabel", typeof (string), typeof (MyControl), new PropertyMetadata(default(string)));
public string MyLabel
{
get { return (string) GetValue(MyLabelProperty); }
set { SetValue(MyLabelProperty, value); }
}
}
Теперь дело в том, что когда я пытаюсь привязать его к созданной мной модели представления, ничего не происходит. Различные элементы кода следующие :
public class MyControlViewModel : ViewModelBase
{
private string name;
public string Name
{
get { return name; }
set { name = value;
RaisePropertyChanged(() => Name);}
}
}
Просмотр объявления модели в App.xaml
<Application.Resources>
<PhoneApp1:MyControlViewModel x:Key="MCVM" />
</Application.Resources>
Объявление элемента управления MainPage.xaml
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<PhoneApp1:MyControl x:Name="testControl" DataContext="{StaticResource MCVM}" MyLabel="{Binding Path=MyLabel}" />
</Grid>
Однако, если я попытаюсь привязать его к какому-либо другому элементу пользовательского интерфейса следующим образом, похоже, это работает?
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<PhoneApp1:MyControl x:Name="testControl" MyLabel="{Binding ElementName=Button, Path=Content}" />
<Button Click="Button_Click" x:Name="Button" Content="Click" />
</Grid>
Я изо всех сил пытался заставить этот простой сценарий работать, и я думаю, что есть что-то глупое, чего мне не хватает?
Любая помощь будет с благодарностью
Комментарии:
1. Вы хотите отобразить myLabel. Текст в текстовом блоке или что?
Ответ №1:
(Это WPF; Я не уверен, что это не 100% аналог WP7 silverlight; я предоставляю более подробную информацию, чтобы помочь вам понять, что происходит, чтобы вы могли найти правильное решение, если мои два варианта недоступны)
По умолчанию привязки имеют корни в DataContext корневого элемента файла xaml (будь то Window или UserControl). Это означает, что
<TextBlock Text="{Binding MyLabel}" />
попытка привязки к DataContext. Итак, по сути, свойство, с которым вы пытаетесь связать, является
MyControl.DataContext.myLabel
Вместо этого необходимо выполнить привязку к следующему:
MyControl.myLabel
Итак, вы должны переназначить привязку к элементу в визуальном дереве, с которым вы хотите связать, к MyControl
классу. Вы можете сделать это несколькими способами…
<TextBlock Text="{Binding MyLabel,
RelativeSource={RelativeSource FindAncestor,
AncestorType=UserControl}" />
распространено, но это должно проходить по дереву и может вызвать некоторые проблемы с производительностью. Я считаю, что проще и рекомендую сделать следующее:
<UserControl x:Class="PhoneApp1.MyControl"
x:Name="root"
x:SnipAttributesBecauseThisIsAnExample="true">
<TextBlock Text="{Binding MyLabel, ElementName=root}" />
</UserControl>
Дайте вашему UserControl имя, затем используйте ElementName для перебазирования привязки к корню визуального дерева.
Я опущу другие, более дурацкие способы достижения этой цели.