2016-11-02 8 views
1

申し訳ありませんが、私は多くの基本的な問題にぶつかる運があります。私はこの特定の問題を回避する方法を考え出すことはできません。新しく作成されたオブジェクトの保護レベルを変更しますか?

このコードは、 "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); 
     } 
} 

そして、ここでメインウィンドウです:

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

'' 'public Code_Behind.Player _Player = new Code_Behind.Player();' ''? – tym32167

+2

'EV001'は良いメンバー名ではありません。もっと読みやすく、自己記述的なものを考えてみましょう。 – Dai

+0

オブジェクトに保護レベルがないため、オブジェクトの保護レベルを変更することはできません。フィールドと変数は行います。 tym32167には1つの答えがあります。 mybirthnameのほうが優れています。私のほうが最善です: 'public String PlayerName {get {return _Player.Name; }} ' –

答えて

0

あなたは視聴者のようなものを書こうとしているように見えます。あなたはプレーヤーを持っていて、彼は名前を持っていて、 "イベント"と考えるストリングのコレクションがあります。私は "出来事"が何を意味するのか理解していませんが、私はあなたがしようとしていると思われるものを推測しました。このためとして

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

は、私はあなたがどこかMainWindowのインスタンスを作成し、それwindowと呼ばれると思いますが、それはそれは、コードの行は、「範囲外」だどこかを定義しています。アナロジーでは、次の丘の後ろにあるものは見えません。あなたが立っている谷間にある物だけが見えます。それは、おおよそ(非常におおよそ、申し訳ありませんが)種類の範囲です。

しかし、あなたがしようとしていることを私の推測に移してみましょう。これは、構築し、実行し、動作します。質問は一切ありません。

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> 
+0

文字通り時間の無駄であるあなたの時間を無駄にしてくれてありがとう。私は正直なところ、このコードのアイデアをすべて得ようと、脳のスープを持っています。しかし、コードを使って私の意図を伝える方が簡単だと思いますので、これを私に説明するのが簡単になります。私がしようとしていることは、{0}の代わりにプレーヤーの名前を使用する 'イベント'を作成することです。イベント自体はテキストボックスに表示され、ボタンを押すと特定のイベントが表示されます。私の問題は、Playerクラスと 'contentControl'クラスの両方が同じクラス内に存在し、MainWindowクラスからオブジェクトインスタンスにアクセスできないことです。 – Zephylir

+0

...私の意図をはっきりさせることができなければ、それについて言及しておいてください。私は文字通り末尾に0文字を残しました – Zephylir

+0

@ Zephylirコードが完全に間違って構成されているため、問題が発生しています。あなたの車が崖の上をまっすぐに行かないということは、あなたに問題があると言っているようです。それは本当に問題ではありません。問題は、あなたが山の周りを歩く道にいなければならないということです。 –

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; }; 
} 
+0

これは素晴らしい解決策ですが、何らかの理由で、 'MainWindow.GetPlayerName()'を使用するとCS0120が起動します。 – Zephylir

+0

@ Zephylir MainWindowオブジェクトを作成する必要があります。 – mybirthname

+0

@ Zephylirエラーメッセージのテキストを読んで、神秘的な理由が全くわからないと思いますか? –

1

大きな問題は、アクセシビリティについてではなく、クラスとオブジェクトの違いを理解していないことです。

MainWindowはクラスです。特定のウィンドウを表すものではありません。オブジェクトを作成するレシピのようなクラスを考えてください。チョコレートチップのクッキーレシピをお持ちの場合、レシピを食べず、特定のクッキーまたはそのレシピに基づいて焼いたクッキーを食べます。

あなたの他のクラスは、最初にプレーヤー名を取得しようとしている特定のウィンドウを知る必要があります。特定のMainWindowオブジェクトへの参照が必要です。

0

あなたがprivateするNamesetを変更するが、それでも許可することができます外界はgetとプロパティを読み取る。

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

これはあなたに新しいGetName()メソッドを作成する必要がなく、所望のfunctionallityを与える必要があります。

関連する問題