更改新创建对象的保护级别?

Changing protection level of newly created object?

好吧,所以我有 运行 的运气解决了很多基本问题。我想不出解决这个特定问题的方法。

这段代码需要访问 "MainWindow" class.

中创建的对象的“_Player.Name” 属性

编辑:这次放上全部代码。这是字符串所在的 Code_Behind。

public class Code_Behind
{

    private static string _Name = "Default";
    public class Player
    {
        public void setName(string name) //Ignore this part, was trying to find a work around here
        {
            _Name = name;
        }
        public string Name
        {
            get { return _Name; }
            set
            {
                _Name = value;
            }
        }
    }
    //contentControl is used to store Content properties
    //UI elements are bound to Content properties to efficiently change their Content
    public class contentControl : INotifyPropertyChanged
    {
        protected void OnPropertyChanged(string name)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }
        public void setEvent(string Event)
        {
            textBoxContent = Event;
        }
        public void addEvent(string Event)
        {
            textBoxContent +="\n" + Event;
        }
        public class Events
        {
            public string EV001 = String.Format("\"Greetings {0}. What can I do for you today?\"", window.PlayerName);
        }
}

这是主窗口之一:

public partial class MainWindow : Window
{
    Code_Behind.contentControl cC = new Code_Behind.contentControl();
    Code_Behind.contentControl.Events Events = new Code_Behind.contentControl.Events();
    Code_Behind.Player _Player = new Code_Behind.Player();
    public string GetPlayerName()
    {
        return _Player.Name;
    }
    public static string _name = "null";
    public MainWindow()
    {
        this.DataContext = cC;
        InitializeComponent();
    }
public string GetPlayerName()
{
    return _Player.Name
}

在您的 MainWindow class 中创建一个方法。之后调用此方法。

public string EV001 = String.Format("\"Greetings {0}. What can I do for you today?\"", 
                       window.GetPlayerName());

如果你愿意,你也可以用 属性 来完成。

public string PlayerName
{
    get { return _Player.Name; };
}

你在这里遇到的更大问题不是关于可访问性,而是不理解 class 和对象之间的区别。

MainWindow 是 class。它不代表任何特定的window。将 class 想象成创建对象的配方。如果你有巧克力饼干食谱,你不会吃食谱,你会吃特定的饼干或按照该食谱烘焙的饼干。

您的其他 class 首先需要知道您正试图从哪个特定 window 获取玩家姓名。它需要对特定 MainWindow 对象的引用。

看起来您正在尝试编写类似于视图模型的东西:您有一个玩家,他有一个名字,并且有一个您认为是 "events" 的字符串集合。我不明白 "events" 是什么意思,但我对我认为你似乎想做的事情进行了最好的猜测。

至于这个:

    public class Events
    {
        public string EV001 = String.Format("\"Greetings {0}. What can I do for you today?\"", window.PlayerName);
    }

我猜你在某处创建了一个 MainWindow 的实例,并将其命名为 window,但它是在某处为该行代码定义的 "out of scope"。以此类推,您看不到下一座山后面的任何东西,只能看到您所站的山谷中的东西。这大致(非常粗略,抱歉)是什么范围。

但让我们继续猜测您要做什么。这将构建、运行和工作。有任何问题,开火。

ViewModels.cs

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Player
{
    public class ViewModelBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string name)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }
    }

    public class MainViewModel : ViewModelBase
    {
        #region Player Property
        private PlayerViewModel _player = default(PlayerViewModel);
        public PlayerViewModel Player
        {
            get { return _player; }
            set
            {
                if (value != _player)
                {
                    _player = value;
                    OnPropertyChanged(nameof(Player));
                    //  Change the player for all the existing events.
                    foreach (var e in Events)
                    {
                        e.Player = Player;
                    }
                }
            }
        }

        #endregion Player Property

        private ObservableCollection<Event> _events = new ObservableCollection<Event>();
        public ObservableCollection<Event> Events
        {
            get { return _events; }
            private set
            {
                if (value != _events)
                {
                    _events = value;
                    OnPropertyChanged(nameof(Events));
                }
            }
        }

        #region Event Methods
        //  This is a BIG guess as to what you're trying to do.
        public void AddGreeting()
        {
            //  Player is "in scope" because Player is a property of this class. 
            if (Player == null)
            {
                throw new Exception("Player is null. You can't greet a player who's not there.");
            }
            Events.Add(new Event("\"Greetings {0}. What can I do for you today?\"", Player));
        }
        #endregion Event Methods
    }

    public class Employee : ViewModelBase
    {
        #region DisplayLtdOccupationId Property
        private bool _displayLtdOccupationId = default(bool);
        public bool DisplayLtdOccupationId
        {
            get { return _displayLtdOccupationId; }
            set
            {
                if (value != _displayLtdOccupationId)
                {
                    _displayLtdOccupationId = value;
                    OnPropertyChanged(nameof(DisplayLtdOccupationId));
                }
            }
        }
        #endregion DisplayLtdOccupationId Property
    }

    public class Event : ViewModelBase
    {
        public Event(String format, PlayerViewModel player)
        {
            _format = format;
            Player = player;
        }
        private String _format = "";

        public String Message
        {
            get { return String.Format(_format, Player.Name); }
        }

        #region Player Property
        private PlayerViewModel _player = default(PlayerViewModel);
        public PlayerViewModel Player
        {
            get { return _player; }
            set
            {
                if (value != _player)
                {
                    _player = value;
                    OnPropertyChanged(nameof(Player));
                    //  When player changes, his name changes, so that 
                    //  means the value of Message will change. 
                    OnPropertyChanged(nameof(Message));
                    if (_player != null)
                    {
                        _player.PropertyChanged += _player_PropertyChanged;
                    }
                }
            }
        }

        private void _player_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            switch (e.PropertyName)
            {
                case nameof(PlayerViewModel.Name):
                    OnPropertyChanged(nameof(Message));
                    break;
            }
        }
        #endregion Player Property
    }

    public class PlayerViewModel : ViewModelBase
    {
        private String _name = default(String);
        public String Name
        {
            get { return _name; }
            set
            {
                if (value != _name)
                {
                    _name = value;
                    OnPropertyChanged(nameof(Name));
                }
            }
        }
    }
}

MainWindow.xaml.cs

using System.Windows;

namespace Player
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            ViewModel = new MainViewModel();

            ViewModel.Player = new PlayerViewModel() { Name = "Ivan the Terrible" };
        }

        //  Just here as a convenience, and to make sure we don't give the DataContext
        //  the wrong kind of viewmodel. 
        public MainViewModel ViewModel
        {
            set { DataContext = value; }
            get { return DataContext as MainViewModel; }
        }

        private void Greeting_Click(object sender, RoutedEventArgs e)
        {
            ViewModel.AddGreeting();
        }
    }
}

MainWindow.xaml

<Window 
    x:Class="Player.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:Player"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
    <Grid>
        <StackPanel Orientation="Vertical">
            <WrapPanel>
                <Button x:Name="Greeting" Content="Greeting" Click="Greeting_Click" />
                <Label>Name: </Label>
                <TextBox Text="{Binding Player.Name}" Width="120" />
            </WrapPanel>
            <ListBox
                ItemsSource="{Binding Events}"
                DisplayMemberPath="Message"
                >
            </ListBox>
        </StackPanel>
    </Grid>
</Window>

你可以把Nameset改成private,但仍然允许外界用get读取属性。

public string Name { get; private set; } = "Default";

这应该可以为您提供所需的功能,而无需创建新的 GetName() 方法。