Настраиваемое свойство и обмен данными между моделями представлений

#c# #wpf #xaml

#c# #wpf #xaml

Вопрос:

Я пытаюсь создать простое приложение, в котором есть элемент управления, определяющий имя игрока и его стиль. Этот элемент управления повторно используется для проигрывателя 1 и проигрывателя 2. Первая цель — установить две группы переключателей, чтобы каждый игрок мог выбирать соответствующим образом. Второй способ заключается в передаче данных из этого элемента управления в модель представления главной страницы. Как мне это сделать?

Вот как выглядит элемент управления:

введите описание изображения здесь

Ниже приведена структура проекта:

введите описание изображения здесь

Player.cs просто содержит ссылку на стиль игрока и его имя

 namespace temp
{
    class Player
    {
        // offensive / defensive
        public string Style { get; set; }

        public string Name { get; set; }
    }
}
  

Он также действует как модель представления для PlayerInfoControl. Вот код для этого:

 <UserControl x:Class="temp.Controls.PersonInfoControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:temp.Controls"
             xmlns:vm="clr-namespace:temp"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">

    <UserControl.Resources>
        <vm:Player x:Key="ViewModel" />
    </UserControl.Resources>

    <Grid DataContext="{StaticResource ViewModel}">
        <StackPanel Orientation="Horizontal" Height="50">
            <StackPanel Margin="0,0,15,0" VerticalAlignment="Center">
                <RadioButton Content="Offense" GroupName="{Binding Group}" />
                <RadioButton Content="Defense" GroupName="{Binding Group}" />
            </StackPanel>
            <StackPanel Margin="0,0,15,0" Orientation="Horizontal" VerticalAlignment="Center">
                <Label Content="Name" />
                <TextBox Width="100" Height="25" Text="{Binding Name}"/>
            </StackPanel>
        </StackPanel>
    </Grid>
</UserControl>
  

MainWindow — это простая сетка, которая дважды определяет playerInfoControl

 <Window x:Class="temp.MainWindow"
        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"
        xmlns:local="clr-namespace:temp"
        xmlns:controls="clr-namespace:temp.Controls"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">

    <Window.Resources>
        <local:MainWindowViewModel x:Key="ViewModel" />
    </Window.Resources>

    <Grid DataContext="{StaticResource ViewModel}">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="160" />
        </Grid.RowDefinitions>

        <controls:PersonInfoControl Grid.Row="0" Group="p1" />
        <controls:PersonInfoControl Grid.Row="1" Group="p2" />
    </Grid>
</Window>
  

Наконец, есть MainWindowViewModel, в который мне нужно передавать данные, которые фиксируются PlayInfoControl.

 namespace temp
{
    class MainWindowViewModel
    {
        Player Player1 = new Player();
        Player Player2 = new Player();
    }
}
  

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

 public partial class PersonInfoControl : UserControl
    {
        public PersonInfoControl()
        {
            InitializeComponent();
        }

        public string Group
        {
            get { return (string)GetValue(GroupProperty); }
            set { SetValue(GroupProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Group.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty GroupProperty =
            DependencyProperty.Register("Group", typeof(string), typeof(Player), new PropertyMetadata(0));
    }
  

Вот как выглядит ошибка:

введите описание изображения здесь

Ответ №1:

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

 new PropertyMetadata(0));
  

с

 new PropertyMetadata(string.Empty));
  

Комментарии:

1. MainWindow.xaml жалуется, что «Тип проигрывателя должен быть производным от DependencyObject»

2. Я расширил Player: DependencyObject и группы теперь работают нормально! Как мне передать данные, которые я собираю с помощью Player.cs, в MainWindowViewModel.cs?