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

时间:2016-11-02 16:53:38

标签: c# wpf object string.format

好吧,所以我很幸运遇到了很多基本问题。我无法解决这个问题。

这段代码需要访问“MainWindow”类中创建的对象的“_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);
        }
}

这是MainWindow的一个:

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();
    }

4 个答案:

答案 0 :(得分:2)

public string GetPlayerName()
{
    return _Player.Name
}

MainWindow课程中创建方法。之后你称之为这种方法。

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

如果你愿意的话,你也可以使用财产。

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

答案 1 :(得分:1)

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

MainWindow是一个班级。它不代表任何特定的窗口。想象一个类就像创建对象的配方一样。如果你有一个巧克力曲奇饼干食谱,你不吃食谱,你吃特定的饼干或根据该食谱烘烤的饼干。

您的其他班级首先需要知道您尝试从哪个特定窗口获取玩家名称。它需要对特定MainWindow对象的引用。

答案 2 :(得分:0)

看起来你正在尝试写一个像viewmodel这样的东西:你有一个玩家,他有一个名字,还有一个你认为是#34;事件&#34 ;.我不明白"事件"本来应该是,但我实现了我认为你似乎想要做的最好的猜测。

至于此:

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

我猜你在某个地方创建了一个MainWindow的实例,并将其命名为window,但它定义的地方超出范围"#34;超出范围"对于那行代码。通过类比,你无法看到下一座山后面的任何东西,只有你所在的山谷中的东西。这是粗略的(非常粗略,对不起) )什么范围是什么。

但让我们继续猜测你正在尝试做什么。这构建,运行和工作。任何问题都会消失。

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>

答案 3 :(得分:0)

您可以将set的{​​{1}}更改为Name,但仍允许外界通过get来阅读该属性。

private

这应该为您提供所需的功能,而无需创建新的public string Name { get; private set; } = "Default"; 方法。