i am using .net win forms i need to set some common properties globally to my win forms like css in web application
ex
form background color=red
button width =100
Text box width=200
font family=arial
how to do this?
how about create a base form that all the other forms inherit.
On the base form you can set the common look and feel.
then if it is necessary to overwrite the common properties you can do so.
EDIT
something like this for the base form.
public partial class BaseForm : Form
{
private Font _font = new Font("Arial", 10);
private Color _backColor = Color.Red;
public BaseForm()
{
InitializeComponent();
}
public override Font Font
{
get { return _font; }
set { _font = value; }
}
public override Color BackColor
{
get { return _backColor; }
set { _backColor = value; }
}
}
and this for the form that you want to display
public partial class Form1 : BaseForm
{
public Form1()
{
InitializeComponent();
}
}
Use the App.Config file or the Settings tab in project properties.
You could create a static class to store them - maybe in a Dictionary perhaps.
Something like this could work:
public static class GlobalData
{
private static Dictionary<string, object> settings;
private static void SetDefaults()
{
settings = new Dictionary<string, object>();
settings.Add("BackgroundColour", "Red");
settings.Add("Width", 100);
}
public static Dictionary<string, object> FormSettings
{
get {
if (settings ==null)
{
SetDefaults();
}
return settings;
}
}
}
EDIT:
You could you use it like this:
this.Width = Convert.ToInt32(GlobalData.FormSettings["Width"].ToString());
Related
I want to style my forms and some controls on my project, e.g. dataGridView.
I know, I can make a method like this an set it for every dataGridView.
public static void StyleDataGridView(DataGridView dg)
{
dg.BorderStyle = BorderStyle.FixedSingle;
dg.RowHeadersVisible = false;
....
}
My question: is there a possibility to do such style code only once in my project? How?
First step with userControl worked very well.
But how to handle the Click, DoubleClick and the CellMouseDown Event?
My code so far:
public partial class ucGridView : UserControl
{
public object DataSource
{
get { return dataGridView.DataSource; }
set { dataGridView.DataSource = value; }
}
public ucGridView()
{
InitializeComponent();
}
}
I have 3 buttons on one usercontrol (usercontrol1.xaml) in the Window . Now on-click of button 1 ,I want to switch the view to another usercontrol (usercontrol2.xaml), which again have 3 buttons and so on.
How to implement in MVVM Pattern in WPF?
Be aware that im using caliburn micro for this example
private IEventAggregator _eventAggregator => IoC.Get<IEventAggregator>(key: nameof(EventAggregator));
private IWindowManager _windowManager => IoC.Get<IWindowManager>(key: nameof(WindowManager));
public ShellViewModel(IEventAggregator eventAggregator)
{
_eventAggregator.Subscribe(this);
}
public string _firstName;
// public ShellViewModel page = new ShellViewModel();
public string FirstName
{
get {
return _firstName;
}
set
{
_firstName = value;
NotifyOfPropertyChange(() => FirstName);
}
}
public ICommand ConvertTextCommand
{
get { return new DelegateCommand(ConvertText); }
}
void ConvertText()
{
//string url = "https://www.google.com/";
string url = FirstName;
string result;
using (HttpClient client = new HttpClient())
{
using (HttpResponseMessage response = client.GetAsync(url).Result)
{
using (HttpContent content = response.Content)
{
result = content.ReadAsStringAsync().Result;
}
}
}
//(MainWindow)Application.Current.MainWindow).txtForm1TextBox.Text = "Some text";
//Application.Current.Resources.Add("PageSource", result);
// NavigationService.NavigateToViewModel<SecondViewModel>("Hello");
_windowManager.ShowWindow(new PageSourceViewModel(_eventAggregator), null);
_eventAggregator.PublishOnUIThread(result);
}
You can check caliburn micro and see that you can just create a new view model in a window manager instance
here is also 2 links to 2 tutorials that helped me solve this issue for MVVM
https://www.youtube.com/watch?v=laPFq3Fhs8k
https://www.youtube.com/watch?v=9kGcE9thwNw&list=LLy8ROdSzpPJnikdZQ1XPZkQ&index=30&t=0s
the first tutorial will help you to get a general idea. The second will help you with events and you can look back to my code and see how i handled a new window instance.
You can also call the same view model for a new instance of the same window like you said in the question
You will also need to make a boostrapper class. For my example i did it like this.
public class Bootstrapper : BootstrapperBase
{
private readonly SimpleContainer _container =
new SimpleContainer();
public Bootstrapper()
{
Initialize();
}
protected override void Configure()
{
_container.Instance<IWindowManager>(new WindowManager());
_container.Singleton<IEventAggregator, EventAggregator>();
_container.PerRequest<ShellViewModel>();
}
protected override void OnStartup(object sender, StartupEventArgs e)
{
_container.Instance<SimpleContainer>(_container);
_container.Singleton<IWindowManager, WindowManager>(key: nameof(WindowManager))
.Singleton<IEventAggregator, EventAggregator>(key: nameof(EventAggregator));
DisplayRootViewFor<ShellViewModel>();
}
protected override object GetInstance(Type service, string key)
{
return _container.GetInstance(service, key);
}
protected override IEnumerable<object> GetAllInstances(Type service)
{
return _container.GetAllInstances(service);
}
protected override void BuildUp(object instance)
{
_container.BuildUp(instance);
}
}
Given a very basic WinForms custom/user control, using System.Windows.Automation it is possible to manipulate built in properties for the custom control.
This is done like this:
public object GetPropertyValue(int propertyId)
{
if (propertyId == AutomationElementIdentifiers.NameProperty.Id)
{
return "Hello World!";
}
}
What I would like to do is expose custom properties to ui automation such as ReadyState, LastAccessed, Etc.
Is this possible?
No, you can't extend the list of properties, and this is complicated by the fact you use Winforms that has a poor UI Automation support (it uses IAccessible with bridges etc.).
What you can do though is add some fake objects to the automation tree, for example, here is a sample Winforms UserControl that does it:
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
Button button = new Button();
button.Location = new Point(32, 28);
button.Size = new Size(75, 23);
button.Text = "MyButton";
Controls.Add(button);
Label label = new Label();
label.Location = new Point(49, 80);
label.Size = new Size(35, 13);
label.Text = "MyLabel";
Controls.Add(label);
MyCustomProp = "MyCustomValue";
}
public string MyCustomProp { get; set; }
protected override AccessibleObject CreateAccessibilityInstance()
{
return new UserControl1AccessibleObject(this);
}
protected class UserControl1AccessibleObject : ControlAccessibleObject
{
public UserControl1AccessibleObject(UserControl1 ownerControl)
: base(ownerControl)
{
}
public new UserControl1 Owner
{
get
{
return (UserControl1)base.Owner;
}
}
public override int GetChildCount()
{
return 1;
}
public override AccessibleObject GetChild(int index)
{
if (index == 0)
return new ValueAccessibleObject("MyCustomProp", Owner.MyCustomProp);
return base.GetChild(index);
}
}
}
public class ValueAccessibleObject : AccessibleObject
{
private string _name;
private string _value;
public ValueAccessibleObject(string name, string value)
{
_name = name;
_value = value;
}
public override AccessibleRole Role
{
get
{
return AccessibleRole.Text; // activate Value pattern
}
}
// note you need to override with member values, base value cannot always store something
public override string Value { get { return _value; } set { _value = value; } }
public override string Name { get { return _name; } }
}
And this is how it appears in the automation tree (using the inspect.exe tool):
Note this technique also supports writing back to the property because it's based on the ValuePattern.
I wanna make a customized window base. So I made a custom window which inherits from Window.
For example:
public class MyWindowBase : Window
{
...
...
}
I wanna override the different Brushes of the super class Window for my own purpose.
In my previous experience, to override methods/properties with no abstract or virtual in the super class need the key word "new".
For example:
public new void DoSomething() { ........ base.DoSomething() ....... }
public new string SomeText { get { ... } set {......} }
It works in my previous work.
However, in this time of dealing with WPF Window, it doesn't work.
I tried to override the different Brushes of the super class Window as follows:
public new Brush BorderBrush
{
get { ... }
set { myBorderBrush = value; base.BorderBrush = null }
}
public new Brush Background
{
get { ... }
set { myBackground = value; base.Backgound = null; }
}
.....
.....
.....
I tried the change the value of the above Brushes in MyWindowBase, it just change the value of the super class Window, it doesn't change the value of myBorderBrush and myBackground.
So, how could I override the methods and properties of the super class Window?
Actually, I want to override the base background so that it will be null or transparent forever, but the changed value will be applied on my own custom Background.
Thank you very much!
If you only want to set the value, then you can set it using
this.BorderBrush = Brushes.Blue;
this.Background = Brushes.Red;
If you wish to overwrite the Property Metadata (for things like default value, property changed logic, or validation), you can use OverrideMetadata
Window.BackgroundProperty.OverrideMetadata(
typeof(MyWindowBase), myPropertyMetadata);
If you simply want to add some logic on Changed, you can use a DependencyPropertyDescriptor
var dpd = DependencyPropertyDescriptor.FromProperty(
Window.BackgroundProperty, typeof(Window));
dpd.AddValueChanged(this.Value, new EventHandler(BackgroundChanged));
private void BackgroundChanged(object sender, EventArgs e)
{
//do the code here
}
And if you're looking to override a Method, and not a Property, then you can use the override keyword
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
}
I'm looking for the best Design for the following situation.
We have many objects form one class, for instance a picture frame. Now each of the picture frames can display 3 types of picture. 1) a face 2) a screenshot 3) empty
Thats easy:
public enum PictureMode
{
Face,
Screen,
None
}
public class PictureFrame {
private PictureMode mode;
public PictureMode Mode
{
get { retrun mode; }
set { /* set currentPicture to the correct one */ }
}
private Image currentPicture;
private Image face;
private Image screen;
private Image empty;
public PictureFrame(Image face, Image screen) {
this.face = face;
this.screen = screen;
mode = PictureMode.None; // Maybe this is our default.
}
}
We can now create some PictureFrames with different pictures and easily change the mode for each one.
Now I want to add a global setter for all PictureFrames. Then each new PictureFrame should take the global setting as the default one. It can later be set to an different through.
Here is my solution, but I want to discuss if there is a better one.
I added a static field PictureFrame.Instances to the PictureFrame class where all PictureFrames are reachable. Now I can iterate over all the PictureFrames to apply the new global mode to all frames.
In addition I have a second static field PictureFrame.GlobalImageMode where I set the global mode if I change it on all Frames and read it in the Constructor of the PictureFrame. The setter for the GlobalImageMode can be static in the PictureFrame class, too.
Just wild shot here...: Why don't you always use getter for current frame mode with a condition in it:
class PictureFrame {
private PictureMode instanceMode;
private static PictureMode? globalMode;
private PictureMode CurrentMode {
get {
return globalMode ?? instanceMode;
}
}
}
If I understand the problem statement correctly, I think this is similar to what you need:
public class Face extends Image { }
public class Screen extends Image { }
public class PictureFrame {
private Image picture = null;
public PictureFrame(Image newPicture) {
this.setPicture(newPicture);
}
public setPicture(Image newPicture) {
this.picture = newPicture;
}
}
public class PictureFactory {
private static Image defaultPicture = null;
public static void setDefaultPicture(Image newPicture) {
PictureFactory.defaultPicture = newPicture;
}
public static Image getDefaultPicture() {
return PictureFactory.defaultPicture;
}
public static PictureFrame getNewPictureFrame() {
return new PictureFrame(PictureFactory.defaultPicture);
}
}
public class PictureFrameManager {
private static PictureManager INSTANCE = new PictureManager();
private Vector<PictureFrame> frames = new Vector<PictureFrame>();
public static PictureFrameManager getInstance() {
return PictureManager.INSTANCE;
}
private PictureFrameManager() {}
private void addPictureFrame(PictureFrame frame) {
this.frames.add(frame);
}
private void setFramesToDefault() {
Image defaultPicture = PictureFactory.getDefaultPicture();
Enumeration<PictureFrame> iFrames = frames.elements();
while(iFrames.hasMoreElements()) {
iFrames.nextElement().setPicture(defaultPicture);
}
}
}
You use it via:
Face face = new Face();
//...do something to load the face object here
PictureFactory.setDefaultPicture(face);
PictureFrame frame = PictureFactory.getNewPictureFrame();
PictureFrameManager manager = PictureFrameManager.getInstance();
manager.addPictureFrame(frame);
Screen screen = new Screen();
//...do something to load the screen object here
PictureFactory.setDefaultPicture(screen);
manager.setFramesToDefault();
Alternately, if you don't want to extend Image or you want to have multiple modes, you could create a decorator object to wrap the image in and say what mode it is.