This works:
<monitor:MonitorDisplay backgroundImage="http://domain.name/logo.png"/>
this doesn't work:
public var log_img:Class;
[source="http://domain.name/logo.jpg"]
...
<monitor:MonitorDisplay backgroundImage="{ log_img }"/>
Are the above 2 essentially the same?
I'm not sure what a monitor:MonitorDisplay is, but it seems to me as if it's backgroundImage property probably expects an image class of some variety, not just class. I'd look at the definition for MonitorDisplay and see what the type is for backgroundImage.
Related
I run often into many problems which leads to refactoring my code...
That is why I want to ask for some recommendations.
The problems I'm running into are:
1) Providing data to XAML
Providing simple data to control value instead of using a value converter. For instance I have a color string like "#FF234243" which is stored in a class. The value for the string is provided by a web application so I can only specify it at runtime.
2) UI for every resolution
In the beginnings of my learning I got told that you can create a UI for every possible resolution, which is stupid.
So I've written a ValueConverter which I bind on an element and as ConverterParameter I give a value like '300' which gets calculated for every possible resolution... But this leads to code like this...
<TextBlock
Height={Binding Converter={StaticResource SizeValue}, ConverterParameter='300'}
/>
3) DependencyProperties vs. NotifyProperties(Properties which implement INotifyPropertyChanged) vs. Properties
I have written a control which takes a list of value and converts them into Buttons which are clickable in the UI. So I did it like this I created a variable which I set as DataContext for this specific Control and validate my data with DataContextChanged but my coworker mentioned that for this reason DependencyProperties where introduced. So I created a DependecyProperty which takes the list of items BUT when the property gets a value I have to render the buttons... So I would have to do something like
public List<string> Buttons
{
get { return (List<string>)GetValue(ButtonsProperty); }
set
{
SetValue(ButtonsProperty, value);
RenderButtons();
}
}
// Using a DependencyProperty as the backing store for Buttons. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ButtonsProperty =
DependencyProperty.Register("Buttons", typeof(List<string>), typeof(MainPage), new PropertyMetadata(""));
private void RenderButtons()
{
ButtonBar.Children.Clear();
ButtonBar.ColumnDefinitions.Clear();
if(Buttons != null)
{
int added = 0;
foreach (var item in Buttons)
{
var cd = new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) };
var btn = new Button() { Content = item };
ButtonBar.ColumnDefinitions.Add(cd);
ButtonBar.Children.Add(btn);
Grid.SetColumn(btn, added);
}
}
}
And have to use it like this:
<Controls:MyControl
x:Name="ButtonBar" Button="{Binding MyButtons}">
</Controls:MyControl>
Since these are a lot of topics I could seperate those but I think that this is a pretty common topic for beginners and I have not found a got explanation or anything else
1. Providing data to XAML
There are two options: prepare data in the ViewModel or to use converter.
To my mind using converter is better since you can have crossplatform viewModel with color like you mentioned in your example and converter will create platform dependent color. We had similar problem with image. On android it should be converted to Bitmap class, while on UWP it's converted to BitmapImage class. In the viewModel we have byte[].
2. UI for every resolution
You don't need to use converter, since Height is specified in effective pixels which will suit all the required resolutions automatically for you. More info can be found at the following link:
https://learn.microsoft.com/en-us/windows/uwp/design/layout/layouts-with-xaml
There are two options how to deal with textblock sizes:
a) Use predefined textblock styles and don't invent the wheel (which is the recommended option):
https://learn.microsoft.com/en-us/windows/uwp/design/style/typography#type-ramp
Or
b) Specify font size in pixels. They are not pixels, but effective pixels. They will be automatically scaled on different devices:
https://learn.microsoft.com/en-us/windows/uwp/design/style/typography#size-and-scaling
Furthermore, use adaptive layout to have different Layout for different screen sizes.
3) DependencyProperties vs. NotifyProperties(Properties which implement INotifyPropertyChanged) vs. Properties
As per your code you can try to use ListView or ItemsControl and define custom item template.
DependencyProperties are created in DependencyObject and are accessible in xaml. All controls are inherited from DependencyObjects. Usually you create them when you want to set them in xaml. They are not stored directly in the objects, but in the global dictionary and resolved at runtime.
DependencyProperties were created long time ago and you can find lots of links which explain them in details:
http://www.wpftutorial.net/dependencyproperties.html
https://techpunch.wordpress.com/2008/09/25/wpf-wf-what-is-a-dependency-property/
When should I use dependency properties in WPF?
What is a dependency property? What is its use?
What is a dependency property?
INotifyPropertyChanged INPC are the central part of MVVM. You bind your view to viewModel which implements INPC and when you change value of the property control is notified and rereads the new value.
Download the following video in high resolution which explains MVVM in details (by Laurent Bugnion):
https://channel9.msdn.com/Events/MIX/MIX11/OPN03
MVVM: Tutorial from start to finish?
Normal properties are used in model classes or when there is no need to notify UI regarding changes.
My view's XAML is only containing a custom control.
A bit further, in a Resource Dictionary, I have a Style for this custom control, and inside this, I have a TextBox. My goal would be to reach this TextBox from the view's code behind, and set it's focus, when the view's DataContext changed.
I tried to use x:Name to give a name to the custom control on the view's XAML, and also give a name to the TextBox inside the control's style (so essentially trying to reach it from code behind like: this.MyCustomControl.SearchTextBox). This did not work.
What would be the best practice to solve this issue?
This is what I would do.
Create a TemplatePart attribute on top of your custom control for the TextBox.
[TemplatePart(Name = "YourTextBoxName", Type = typeof(TextBox))]
Then inside the OnApplyTemplate override method, get a reference of the TextBox.
// You might want to add property error handling here
// so if the TextBox is not found, throw an exception.
// Doing so forces other people will have to implement
// the SAME PART in their own stylings.
_textBox = (TextBox)GetTemplateChild("YourTextBoxName");
Then all you need is to create a public method SetFocus that your code behind class can have access to.
public void SetFocus() => _textBox.Focus(FocusState.Programmatic);
Try visual tree helper
VisualTreeHelper.GetChild(object, index)
msdn link
I have a control that consists of a button and a textbox.
I wanted to set the input scope of the textbox, so I introduced a new dependency property:
public InputScope InputScope
{
get { return (InputScope)GetValue(InputScopeProperty); }
set { SetValue(InputScopeProperty, value); } // Notify prop change
}
public static readonly DependencyProperty InputScopeProperty =
DependencyProperty.Register(nameof(InputScope), typeof(InputScope), typeof(SearchControl), new PropertyMetadata(DependencyProperty.UnsetValue));
In XAML:
<controls:SearchControl InputScope="Number" /> <!-- etc... -->
(Obviously assigning it to the InputScope property of the textbox in the style of this custom control.)
My problem: While this works, the numeric keyboard gets shown when focused, but I have blue underline in the XAML, and also an error message: The TypeConverter for "InputScope" does not support converting from a string.
Is there a way to fix it without a dirty hack?
Is there a way to fix it without a dirty hack?
You could implement a type converter. Please refer to Tim Heuer's blog post for more information and an example:
Implementing a type converter in UWP XAML: http://timheuer.com/blog/archive/2017/02/15/implement-type-converter-uwp-winrt-windows-10-xaml.aspx
You may also want to read this:
WinRT Replacement for System.ComponentModel.TypeConverter
I want to make a panel on form visible/invisible at runtime like this:
wxPanel* wxp;
wxp->Hide();
...
wxp->Show();
Is it possible in some way?
You should be able to do it exactly like that as wxPanel inherits from wxWindow which provides methods called Hide and Show.
So the following code should work:
wxPanel* wxp = new wxPanel(parent);
wxp->Hide();
...
wxp->Show();
As far as I can judge, the CSS-Rule "dijitRequired" is used to mark a required input field. Yet, this style is not set when I apply the "required"-Attribute to a dijit, for example, a date dijit:
The Dijit is built as follows:
<input dojoType="dijit.form.DateTextBox" class="l" id="datumsTestID" name="datumsTest" tabindex="5" value="2009-01-01" />
The Attribute is set with the following Javscript code
dijit.byId('datumsTestID').attr('required', true)
Am I doing something wrong or is the style "dijitRequired" not intended to be used as I assume?
For my purposes, I patched ValidationTextBox.js to set/unset the class, but is there a cleaner (meaning: more correct) way to set the class or can I style required fields using other attributes?
ValidationTextBox.js, Dojo 1.3, Line 116
_setRequiredAttr:function(_12){
this.required=_12;
if (_12) dojo.addClass(this.domNode, "dijitRequired");
else dojo.removeClass(this.domNode, "dijitRequired");
dijit.setWaiState(this.focusNode,"required",_12);
this._refreshState();
}
Hmm, I don't see that code in ValidationTextBox.js or anywhere else. My _setRequiredAttr() in 1.3 is:
_setRequiredAttr: function(/*Boolean*/ value){
this.required = value;
dijit.setWaiState(this.focusNode,"required", value);
this._refreshState();
}
Actually I don't see any references to dijitRequired at all, maybe that's something you added to your local copy?
Setting dijitRequired is not enough. dijit.form.DateTextBox has its own internal state. Even if required attribute is set, this widget display error only when it has been blurred. You can disable this mechanism using such subclass:
dojo.provide("my.DateTextBox");
dojo.require("dijit.form.DateTextBox");
dojo.declare("my.DateTextBox", dijit.form.DateTextBox, {
_setRequiredAttr: function(required){
this._hasBeenBlurred = true;
this.inherited(arguments);
}
});