I want to call the method from the codebehind of a window that is NOT the MainWindow in my WPF application, casting the window type as I do it.
ClientCallBack.cs:
using ChattingInterfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace ChatClient
{
[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
public class ClientCallback : IClient
{
public void GetMessage(string message, string userName)
{
//get casted instance of chat client window (NOT MainWindow!)
}
}
}
ChatWPFClient.xaml.cs:
using ChattingInterfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace ChatClient
{
/// <summary>
/// Interaction logic for ChatWPFClient.xaml
/// </summary>
public partial class ChatWPFClient : Window
{
public static IChattingService Server;
private static DuplexChannelFactory<IChattingService> _channelFactory;
public ChatWPFClient()
{
InitializeComponent();
_channelFactory = new DuplexChannelFactory<IChattingService>(new ClientCallback(), "ChattingServiceEndpoint");
Server = _channelFactory.CreateChannel();
}
private void sendMessage(object sender, RoutedEventArgs e)
{
MessageBox.Show("Not available yet!");
}
public void TakeMessage(string message, string userName)
{
chatBox.Text += userName + ": " + message + "\n";
}
}
}
How can I call the TakeMessage of this method in the other class so I can use that codebehind window to populate the XAML file for ChatWPFClient.xaml? Thanks in advance!
First create an interface that you can pass to the ClientCallback
public interface IMessageHandler
{
void TakeMessage(string message, string userName);
}
Then in the ClientCallBack take the interface as a parameter in the constructor.
[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
public class ClientCallback : IClient
{
private IMessageHandler messageHandler;
public ClientCallBack(IMessageHandler messageHandler)
{
this.messageHandler = messageHandler;
}
public void GetMessage(string message, string userName)
{
messageHandler.TakeMessage(message, userName);
}
}
Use the interface for the ChatWpfClient and pass the instance in the constructor.
public partial class ChatWPFClient : Window, IMessageHandler
{
...
public ChatWPFClient()
{
InitializeComponent();
_channelFactory = new DuplexChannelFactory<IChattingService>(new ClientCallback(this), "ChattingServiceEndpoint");
Server = _channelFactory.CreateChannel();
}
...
// This is a part of the interface now and needs to be implemented here
public void TakeMessage(string message, string userName)
{
chatBox.Text += userName + ": " + message + "\n";
}
}
Also you could just implement the IClient on your ChatWPFClient class and decorate with the CallBackBehavior attribute and just pass itself as the callback. But don't think this is recommended, seems weird.
_channelFactory = new DuplexChannelFactory<IChattingService>(this, "ChattingServiceEndpoint");
Related
I want to autoscroll WPF ListBox to bottom automatically. I have two classes - one is Timer.cs and another one is MainWindow.xaml.cs
Here is Timer.cs:
using System;
using System.Configuration;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace Importer_WPF
{
class Timer
{
public static readonly string MinutesExecution = ConfigurationManager.AppSettings["MinutesExecution"];
static System.Threading.Timer timer;
public static void StartTimer()
{
var startTimeSpan = TimeSpan.Zero;
var periodTimeSpan = TimeSpan.FromMinutes(Convert.ToDouble(MinutesExecution));
timer = new System.Threading.Timer((e) =>
{
Task.Delay(100).ContinueWith(_ => App.Current.Dispatcher.Invoke(() => MainWindow.Names.Add(DateTime.Now.ToString())));
MainWindow.AutoScroll(); // Problem is here
}, null, startTimeSpan, periodTimeSpan);
}
public static void StopTimer()
{
timer.Change(Timeout.Infinite, Timeout.Infinite);
}
}
}
MainWindow.xaml.cs:
using System;
using System.Collections.ObjectModel;
using System.Configuration;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Input;
namespace Importer_WPF
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public static ObservableCollection<string> Names { get; set; }
public static bool IsCheckedYes { get; set; }
[Obsolete]
public MainWindow()
{
InitializeComponent();
}
public void AutoScroll()
{
int itemCount = ConsoleOutput.Items.Count - 1;
if (itemCount > -1)
ConsoleOutput.ScrollIntoView(ConsoleOutput.Items[itemCount]);
}
}
}
Debugger is giving this message:
Severity Code Description Project File Line Suppression State
Error CS0120 An object reference is required for the non-static field,
method, or property 'MainWindow.AutoScroll()'
Any hints how to edit code structure so it will not produce errors?
You need to get a reference to the instance of mainwindow class which is in memory.
((MainWindow)Application.Current.MainWindow).AutoScroll();
A class named Round is a level design in a adventure game.Its filed number indicate which level the player is in. Different level will have different figures to guess. The figures are produced by field FigureFactory.
The question is: using Ninject for dependency injection, how can I set the cooresponding FigureFactory to the variable round, according to the field number? For instance, when field number==1, the cooresponding factory is FigureFactory1, when field number==2, the cooresponding factory is FigureFactory2?
using GuessFigure.Model.Factory;
using Ninject;
using Ninject.Modules;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Ninject.Planning.Bindings;
namespace GuessFigure.Model
{
class Round
{
private int number=1;
private FigureFactory figureFactory;
[Inject]
internal void SetFigureFactory(FigureFactory figureFactory)
{
this.figureFactory = figureFactory;
}
public int[] GetCurrentRoundFigures()
{
return figureFactory.Produce(number);
}
}
//this not work, help please
class RoundModule : NinjectModule
{
public override void Load()
{
Bind<FigureFactory>().To<FigureFactoryRound1>().When(request=>request.ParentRequest.Target.Type.GetField("number").Equals(1));
Bind<FigureFactory>().To<FigureFactoryRound2>().When(request => request.Target.Type.GetField("number").Equals(2));
Bind<FigureFactory>().To<FigureFactoryRound3>().When(request => request.Target.Type.GetField("number").Equals(3));
Bind<FigureFactory>().To<FigureFactoryRound4>().When(request => request.Target.Type.GetField("number").Equals(4));
Bind<FigureFactory>().To<FigureFactoryRound5>().When(request => request.Target.Type.GetField("number").Equals(5));
}
}
}
Factory Method Pattern implementation:
using System;
namespace GuessFigure.Model
{
abstract class FigureFactory
{
protected int figureNumber;
public FigureFactory(int figureNumber)
{
this.figureNumber = figureNumber;
}
internal int[] Produce()
{
int[] figureArray = new int[figureNumber];
for (int i = 0; i < figureNumber; i++)
{
figureArray[i] = Algorithm(i + 1);
}
return figureArray;
}
abstract protected int Algorithm(int inputNumber);
}
}
Concrete Factory(there are still some like this);
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GuessFigure.Model
{
class FigureFactoryRound1 : FigureFactory
{
public FigureFactoryRound1(int figureNumber) : base(figureNumber)
{
}
protected override int Algorithm(int inputNumber)
{
return inputNumber;
}
}
}
class FigureFactoryRound3 :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GuessFigure.Model.Factory
{
class FigureFactoryRound3 : FigureFactory
{
public FigureFactoryRound3(int figureNumber) : base(figureNumber)
{
}
protected override int Algorithm(int inputNumber)
{
return (int) Math.Pow( inputNumber,2) ;
}
}
}
class FigureFactoryRound4 :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GuessFigure.Model.Factory
{
class FigureFactoryRound4 : FigureFactory
{
public FigureFactoryRound4(int figureNumber) : base(figureNumber)
{
}
protected override int Algorithm(int inputNumber)
{
return (int)Math.Pow(inputNumber, 3);
}
}
}
Usage:
IKernel kernel = new StandardKernel(new RoundModule());
Round round = new Model.Round();
round.SetFigureFactory(kernel.Get<FigureFactory>());
int[] array=round.GetCurrentRoundFigures();
Currently I am trying to code a WPF application that will store books and users for an imaginary library(I need to prove someone wrong). In my code, I have a class for Books and one for users. Inside of each will be a static list that keeps track of them all. What I would like to do is list out all the books and users so the viewer can see them. I thought I could do this with a scrollview and add labels to it that store the information(This would be in a separate window than the main screen, you would get there by pressing a button). However, I have been having some trouble with this.
LibraryCore:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LibraryCore
{
class User
{
}
class Books
{
public static List<Books> bookslist = new List<Books>();
public static void NewBook(string _title, string _author, string _publisher, int _isbn, int _count = 1)
{
bookslist.Add(new Books(_title, _author, _publisher, _isbn, _count));
}
public static void AddBook(string _title, int _amount)
{
bookslist[bookslist.FindIndex(b => b.Title.ToUpper() == _title.ToUpper())].Count += _amount;
}
public List<Books> currentLoans = new List<Books>();
public string Publisher { get; private set; }
public string Author { get; private set; }
public string Title { get; private set; }
public int ISBN { get; private set; }
public int Count { get; private set; }
Books(string _title, string _author, string _publisher, int _isbn, int _count = 1)
{
Title = _title;
Author = _author;
Publisher = _publisher;
ISBN = _isbn;
Count = _count;
}
}
}
MainWindow:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using LibraryCore;
namespace LibraryLikeWpf
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void btnNewBook_Click(object sender, RoutedEventArgs e)
{
Books.NewBook("Odessy", "SOME OLD GUY", "Athens Inc.", 0);
//Books.NewBook("OLD YELLER", "SOME OLD GUY", "Athens Inc.", 2);
//Books.NewBook("This old man", "SOME OLD GUY", "Athens Inc.", 1);
}
private void btnInfo_Click(object sender, RoutedEventArgs e)
{
BookList bookList = new BookList();
bookList.Show();
}
}
}
BookListWindow:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using LibraryCore;
namespace LibraryLikeWpf
{
/// <summary>
/// Interaction logic for BookList.xaml
/// </summary>
public partial class BookList : Window
{
public BookList()
{
InitializeComponent();
for(int b = 0; b < Books.bookslist.Count; b++)
{
Label lbl = new Label();
lbl.VerticalAlignment = VerticalAlignment.Top;
lbl.Content = String.Format("Title: {0} Author: {1} Publisher: {2} ISBN: {3}",Books.bookslist[b].Title,Books.bookslist[b].Author, Books.bookslist[b].Publisher, Books.bookslist[b].ISBN);
lbl.Width = 100000;
scrollGrid.Children.Add(lbl);
}
}
}
}
This code works, but if I add several Books, the BookListWindow will just overlap the labels and I would like to know how to change their position when they are instantiated. Also, the labels get cut off even though their width shouldn't inhibit that. Why does that happen and how can I fix it? Also, is there a better way to list out ALL of the items in a list in a better looking way?
If your are using XAML, try to use ListView with Binding.
Create a ObservableCollection of Books and bind this to your ListView, this way you can control show your items are shown.
I have two solutions TranferService and Sender. TranferService has WCF service and IISHost to host that service. In Sender solution i have windows forms application. In that form i used button to browse and select file, text box to display selected file path, and another button(Send) to transfer that file through WCF service. But i am unable to access textbox value in the transfer solution. it shows"the name does not exist in the current context".
Code for TransferService
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace TransferService
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "TransferService" in both code and config file together.
public class TransferService : ITransferService
{
public File DownloadDocument()
{
File file = new File();
String path = txtSelectFilePath.Text;
file.Content = System.IO.File.ReadAllBytes(#path);
//file.Name = "ImagingDevices.exe";
return file;
}
}
}
I am getting error on this line
String path = txtSelectFilePath.Text;
code for form.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Sender
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Browse_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
txtSelectFilePath.Text = openFileDialog1.FileName;
}
}
private void Send_Click(object sender, EventArgs e)
{
TransferService.TransferServiceClient client = new TransferService.TransferServiceClient();
TransferService.File file = client.DownloadDocument();
System.IO.File.WriteAllBytes(#"C:\DownloadedFiles\" + file.Name, file.Content);
MessageBox.Show(file.Name + " is downloaded");
}
}
}
Code for ITransferService.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace TransferService
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "ITransferService" in both code and config file together.
[ServiceContract]
public interface ITransferService
{
[OperationContract]
File DownloadDocument();
}
[DataContract]
public class File
{
[DataMember]
public string Name { get; set; }
[DataMember]
public byte[] Content { get; set; }
}
}
Thanx a lot in advance..........
Then create a constructor to your class that receives a path as string something like this:
public class TransferService : ITransferService
{
private string _path;
public TransferService(string path) {
_path = path
}
public File DownloadDocument()
{
File file = new File();
//String path = txtSelectFilePath.Text;
file.Content = System.IO.File.ReadAllBytes(_path);
//file.Name = "ImagingDevices.exe";
return file;
}
}
and then on form.cs
TransferService.TransferServiceClient client = new TransferService.TransferServiceClient(txtSelectFilePath.Text);
Hey guys im new with the NSubstitute framework. I'm trying to test some of my classes, but when i use NSubstitute to check received calls it says received no matching calls.
I'm trying to test if the method Tick() is receiving update() from track class.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ATM_System.Event;
using ATM_System.EventDetection;
using ATM_System.Region;
using ATM_System.Track;
namespace ATM_System
{
public class ATM
{
private List<ITrack> _tracks;
private IRegion _region;
private List<IEventDetection> _eventdetects;
private List<IEvent> _events;
public ATM()
{
_tracks = new List<ITrack>();
_region = new Region.Region(100000,100000); //could be changed by user
_events = new List<IEvent>();
_eventdetects = new List<IEventDetection>();
}
public void Tick()
{
// update track positions
foreach (var track1 in _tracks)
{
track1.update();
}
//check for events
foreach (var detector in _eventdetects)
{
_events.AddRange(detector.DetectEvent(_tracks));
}
//handle events and output
foreach (var event1 in _events)
{
event1.HandleEvent();
event1.LogEvent();
}
}
public void IncomingTrack(ITrack track)
{
//add incoming track
_tracks.Add(track);
}
}
}
TEST FILE
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ATM_System.Event;
using ATM_System.EventDetection;
using ATM_System.Track;
using NUnit.Framework;
using NSubstitute;
namespace ATM_System.Tests.Unit
{
[TestFixture]
class ATMUnitTests
{
private ATM _uut;
private ITrack _track;
private IEvent _event;
private IEventDetection _eventDetection;
[SetUp]
public void Setup()
{
_track = Substitute.For<ITrack>();
_event = Substitute.For<IEvent>();
_eventDetection = Substitute.For<IEventDetection>();
_uut = new ATM();
}
[Test]
public void Tick_UpdateTracks_TracksUpdated()
{
_uut.Tick();
_track.Received().update();
}
}
}
You forgot to include _track in notification receivers. It simply hasn't subscribed to event and as a result is not notified. To fix simply call your IncomingTrack method:
[Test]
public void Tick_UpdateTracks_TracksUpdated()
{
_uut.IncomingTrack(_track);
_uut.Tick();
_track.Received().update();
}