From: shapper on
On Nov 20, 7:25 pm, Peter Duniho <no.peted.s...(a)no.nwlink.spam.com>
wrote:

> I don't know.  As I said, a concise-but-complete code example would go a
> long way to improving your question.

I am not sure if the example that you are asking is what I am going to
post.

The objectives are:
1. Display the result of Console.WriteLine in Console and in
TextBlock ...
... From Window1 and from Test.Run() when the button is clicked.

2. Write the result of a command in Console and TextBlock ...
In my code I was checking the messages of minimizing the JS and CSS
code.
I didn't implement this part. Maybe saving or opening a file?

I think the TextWriterProxy would be a better option than my initial
approach as it even allows to write to other targets.

This said, this is my code (I hope this is what you are asking):

-- BEGIN Window1.xaml ---

<Window x:Class="ConsoleTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
</Window>


-- BEGIN Window1.xaml.cs ---

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
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;

// ConsoleTest
namespace ConsoleTest {

public partial class Window1: Window {

#region Constructors

public Window1() {

// Initialize component
InitializeComponent();

// Define proxy
TextWriterProxy proxy = new TextWriterProxy();
proxy.Add(Console.Out);
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
proxy.Add(sw);
Console.SetOut(proxy);

// Dock panel
DockPanel content = new DockPanel();

// Menu
Menu menu = new Menu();
menu.Items.Add(new MenuItem { Command = TestCommands.Test,
Header = "Test" });
DockPanel.SetDock(menu, Dock.Top);
content.Children.Add(menu);

// Text block
TextBlock output = new TextBlock();
DockPanel.SetDock(output, Dock.Bottom);
content.Children.Add(output);
Content = content;

// 1: Use Text Writer Proxy - NOT WORKING FROM Test.Run()
proxy.WriteLine("Write from Window1");
output.Text = sb.ToString();

// 2: Use Console Log - NOT WORKING
//using (ConsoleLog cl = new ConsoleLog(output, Console.Out)) {
// Console.SetOut(cl);
//}
//Console.WriteLine("Write from Window1");

} // Start

#endregion // Constructors

} // Start

} // ConsoleTest

// ConsoleLog
public class ConsoleLog : TextWriter {

public override Encoding Encoding { get { return
Encoding.Default; } } // Encoding
private TextWriter _writer;
private TextBlock _output;

public ConsoleLog(TextBlock output, TextWriter writer) {
_writer = writer;
_output = output;
} // ConsoleLog

public override void Write(String s) {

_writer.Write(s);
_output.Text = String.Concat(_output.Text, s);

} // Write

} // ConsoleLog

// TestCommands
public static class TestCommands {

public static ICommand Test { get { return new TestCommand(); } }

public class TestCommand : ICommand {

// CanExecute
public Boolean CanExecute(Object parameter) {
return true;
} // CanExecute

// CanExecuteChanged
public event EventHandler CanExecuteChanged {
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
} // CanExecuteChanged

// Execute
public void Execute(Object parameter) {
TestService.Run();
} // Execute

} // TestCommand

} // TestCommands

// TestService
public static class TestService {

#region Methods

public static void Run() {
Console.WriteLine("Write from Test Service");
} // Run

#endregion // Methods

} // TestService

public class TextWriterProxy : TextWriter {

private List<TextWriter> _writers = new List<TextWriter>();

public override Encoding Encoding { get { return
Encoding.Default; } } // Encoding

public override string NewLine {
get { return base.NewLine; }
set {
foreach (TextWriter tw in _writers)
tw.NewLine = value;
base.NewLine = value;
}
} // NewLine

public void Add(TextWriter writer) {
if (!_writers.Contains(writer))
_writers.Add(writer);
} // Add

public bool Remove(TextWriter writer) {
return _writers.Remove(writer);
} // Remove

public override void Write(char value) {
foreach (TextWriter tw in _writers)
tw.Write(value);
base.Write(value);
} // Write

public override void Close() {
foreach (TextWriter tw in _writers)
tw.Close();
base.Close();
} // Close

protected override void Dispose(bool disposing) {
foreach (TextWriter tw in _writers)
tw.Dispose();
base.Dispose(disposing);
} // Dispose

public override void Flush() {
foreach (TextWriter tw in _writers)
tw.Flush();
base.Flush();
} // Flush

} // TextWriterProxy


Thank You,
Miguel
From: Peter Duniho on
shapper wrote:
> On Nov 20, 7:25 pm, Peter Duniho <no.peted.s...(a)no.nwlink.spam.com>
> wrote:
>
>> I don't know. As I said, a concise-but-complete code example would go a
>> long way to improving your question.
>
> I am not sure if the example that you are asking is what I am going to
> post.
>
> The objectives are:
> 1. Display the result of Console.WriteLine in Console and in
> TextBlock ...
> ... From Window1 and from Test.Run() when the button is clicked.
>
> 2. Write the result of a command in Console and TextBlock ...
> In my code I was checking the messages of minimizing the JS and CSS
> code.
> I didn't implement this part. Maybe saving or opening a file?
>
> I think the TextWriterProxy would be a better option than my initial
> approach as it even allows to write to other targets.
>
> This said, this is my code (I hope this is what you are asking): [...]

Well, the code you posted isn't complete, because you call a method not
declared in the code you posted (InitializeComponent()).

That said, the code you did post looks much like the code I already
responded to, where I explained that simply redirecting the output to
your proxy which in turn redirects output to your StringWriter cannot in
and of itself cause any update to the TextBlock control.

As I wrote before, you need some mechanism for specifically updating the
TextBlock control any time something is written to your proxy. For
example, yet another TextWriter that wraps updates to the TextBlock
control. Add that TextWriter to your proxy (which is really a kind of
"T filter"), and then in that TextWriter, copy text passed via the
Write() method to the TextBlock.

Nothing about the expanded code example you've posted leads me to change
my mind on that point. :)

Pete
From: shapper on
On Nov 20, 10:07 pm, Peter Duniho <no.peted.s...(a)no.nwlink.spam.com>
wrote:
> shapper wrote:
> > On Nov 20, 7:25 pm, Peter Duniho <no.peted.s...(a)no.nwlink.spam.com>
> > wrote:
>
> >> I don't know.  As I said, a concise-but-complete code example would go a
> >> long way to improving your question.
>
> > I am not sure if the example that you are asking is what I am going to
> > post.
>
> > The objectives are:
> > 1. Display the result of Console.WriteLine in Console and in
> > TextBlock ...
> >    ... From Window1 and from Test.Run() when the button is clicked.
>
> > 2. Write the result of a command in Console and TextBlock ...
> >    In my code I was checking the messages of minimizing the JS and CSS
> > code.
> >    I didn't implement this part. Maybe saving or opening a file?
>
> > I think the TextWriterProxy would be a better option than my initial
> > approach as it even allows to write to other targets.
>
> > This said, this is my code (I hope this is what you are asking): [...]
>
> Well, the code you posted isn't complete, because you call a method not
> declared in the code you posted (InitializeComponent()).

It is a part of WPF code and is present in all Windows or User
Controls. A better description:

"The call to InitializeComponent() (which is usually called in the
default constructor of at least Window and UserControls) is actually a
method call to the partial class of the control (rather than a call up
the object hierarchy as I first expected).

This method locates a URI to the XAML for the Window/UserControl that
is loading, and passes it to the
System.Windows.Application.LoadComponent() static method. LoadComponent
() loads the XAML file that is located at the passed in URI, and
converts it to an instance of the object that is specified by the root
element of the XAML file.

In more detail, LoadComponent creates and instance of the XamlParser,
and builds a tree of the XAML. Each node is parsed by the
XamlParser.ProcessXamlNode(). This gets passed to the BamlRecordWriter
class. Sometime after this I get a bit lost in how the BAML is
converted to objects, but this may be enough to help you on the path
to enlightenment.

Note: Interestingly, the InitializeComponent is an method on the
System.Windows.Markup.IComponentConnector interface, of which Window/
UserControls implement in the partial generated class."

> That said, the code you did post looks much like the code I already
> responded to, where I explained that simply redirecting the output to
> your proxy which in turn redirects output to your StringWriter cannot in
> and of itself cause any update to the TextBlock control.
>
> As I wrote before, you need some mechanism for specifically updating the
> TextBlock control any time something is written to your proxy.  For
> example, yet another TextWriter that wraps updates to the TextBlock
> control.  Add that TextWriter to your proxy (which is really a kind of
> "T filter"), and then in that TextWriter, copy text passed via the
> Write() method to the TextBlock.

I am a little bit lost about the code you suggesting but what comes to
mind is to add a ConsoleLog to the proxy.
Since ConsoleLog already implements TextWriter and works with
TextBlock ...

But I think I need to make some changes in it ... I am confused. :-)

> Nothing about the expanded code example you've posted leads me to change
> my mind on that point.  :)

See that my "strange" initial code said it all? :-P

Miguel
From: Peter Duniho on
shapper wrote:
> [...]
>> Nothing about the expanded code example you've posted leads me to change
>> my mind on that point. :)
>
> See that my "strange" initial code said it all? :-P

No. It's just that your subsequent post didn't add anything to it.
From: shapper on
On Nov 21, 7:13 pm, Peter Duniho <no.peted.s...(a)no.nwlink.spam.com>
wrote:
> shapper wrote:
> > [...]
> >> Nothing about the expanded code example you've posted leads me to change
> >> my mind on that point.  :)
>
> > See that my "strange" initial code said it all? :-P
>
> No.  It's just that your subsequent post didn't add anything to it.

I a not sure but maybe turning the proxy into a static class would
make it globally and solve the problem.

I am trying the following:

public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();

ConsoleWriter.TextBlock = tbOutput;
ConsoleWriter.WriteLine("TEST");
}
}

public static class ConsoleWriter
{
public static TextBlock TextBlock { get; set; }

public static void WriteLine(string message)
{
Console.WriteLine(message);
TextBlock.Text = message;
}
}

But instead of using this approach maybe have the ConsoleWriter wrapp
the TextBlock and the Proxy ..