Setter not working for margin on user control in WPF - c#

I have created a UserControl that is working just fine. If I set the margin in code all goes well:
<cbtn:BillLister Margin="10,5,10,5" />
However, when i try to set it for everyone of those that are in the wrappannel they are in, this doesn't work:
<WrapPanel.Resources>
<Style TargetType="cbtn:BillLister">
<Style.Setters>
<Setter Property="Margin" Value="150,35,50,35" />
<Setter Property="Background" Value="Black"/>
</Style.Setters>
</Style>
The Background property is working however, so i know that it is targeting the correct UserControls.
I did find this: How to give my custom control an overridable default margin? I tried what he did in there, and still no change.
public partial class BillLister : UserControl
{
public BillLister()
{
InitializeComponent();
Labelcount.Content = "0";
}
static BillLister()
{
MarginProperty.OverrideMetadata(typeof(BillLister), new FrameworkPropertyMetadata(new Thickness(30, 130, 30, 30)));
}
...
Does anyone have any idea what might be going on here? I would hate to have to set the margin on each one manually.
Update to clarify: When trying the second version i don't use the inline margin from the first one. Also, the margin fromthe second example is not applied at all.

Related

Is it possible to bind value for FontSize from a ResourceDictionary?

I am working on an app where I am in need of changeing the text size from small to big with help of a settings page.
I have decoupled my code from the app.xaml and added some references there instread from some ResourceDictionary i've created.
I am now wondering if its possible to bind the value.
<Style x:Key="articleBodyText" TargetType="Label">
<Setter Property="FontSize" Value="{Binding SelectedFontSize}"/>
<Setter Property="Padding" Value="0,0,0,15"/>
<Setter Property="TextColor" Value="{AppThemeBinding Dark={StaticResource LightPrimaryColor}, Light={StaticResource DarkPrimaryColor}}"></Setter>
</Style>
Define a property of type double
private double _SelectedFontSize;
public double SelectedFontSize
{
get => _SelectedFontSize;
set => SetProperty(ref _SelectedFontSize, value); //INotifyProertyChanged
}
Supposed you have defined CustomSmall resource either in xaml or in code:
Resources.Add("CustomSmall", 10);
Resources.Add("CustomLarge", 22);
Resources.TryGetValue("CustomSmall", out var fontSize);
FontSize = (double)fontSize;
Related question
How can I add application resources to my C# backend for the application instead of in the XAML file?
Value=new Binding(16) for example should set the Fontsize to 16. So you pass the chosen value from you're settings Page and use it in the binding.

The member "Height" is not recognized or is not accessible

I want to set the Height property in a setter of a style but it shows the error at design time. It will work without problem at runtine.
The type inherits from control, which inherits for framework element, that has a Height property.
Can someone explain why and how I can fix it or get rid of the message?
<Style TargetType="{x:Type materialDesign:PackIcon}"
BasedOn="{StaticResource {x:Type materialDesign:PackIcon}}">
<Setter Property="Height"
Value="30" />
</Style>
I think it has nothing to do with the class itself, but here is the code anyway:
Apparently it has to do with the class itself:
materialDesign:PackIcon
Edit1:
After prefixing with FrameworkElement I get the error messagages:
PackIconExtension' type must derive from FrameworkElement or FrameworkContentElement.
and
The resource "materialDesign:PackIcon" could not be resolved.
Seemingly it is an extension - but this surpasses my wpf knowledge.
<Setter Property="FrameworkElement.Height"
Value="30" />
Edit2:
Here is the code of the extension: materialDesign:PackIconExtension

Wpf Custom Popup control and application theming: Resources not found

I have an app where I set a theme (ResourceDictionary) on the main Window. Then all children "inherits" styles, themes etc. via the DynamicResourceExtension. This works.
However, i have a custom Popup control to handle long press animation on buttons:
class LongPressAnimationControl : Popup
{
static LongPressAnimationControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(LongPressAnimationControl),
new FrameworkPropertyMetadata(typeof(LongPressAnimationControl)));
}
/* Various DP's, events, properties, methods ETC. */
}
with a default style in Generic.xaml:
<Style TargetType="{x:Type controls:LongPressAnimationControl}">
<Setter Property="Delay" Value="00:00:00.500" />
<Setter Property="Duration" Value="00:00:01.000" />
<Setter Property="Image" Value="{StaticResource Image.LongPress}" />
<Setter Property="EasingFunction"><Setter.Value><CubicEase/></Setter.Value></Setter>
</Style>
This works. the properties change to the ones set in the style.
However, i would like the popup to use a style defined in the Theme.xaml so the properties etc. can be themed.
If i move the style to my Theme.xaml, then the style is not picked up (properties does not change).
I've also tried to add a key to the Style, and a resource reference in code, like so:
public LongPressAnimationControl()
{
SetResourceReference(StyleProperty, "LongPressAnimationControlStyle");
//....
}
Anyone with an idea of how to solve this?
You should include Theme.xaml in App.xaml resource, so WPF can find the resource.

Change color of control to default

i do have a textbox. When there is error i set borderbrush to new SolidColorBrush(Colors.Red). When error is fixed, i want to switch to default color of border of a textbox. I am doing it in codebehind not xaml.
However it is system dependent. I noticed there is something like
SystemColor.ActiveControl etc. Should i use these and if yes, which one is default border of textbox?
Also i noticed there is something like Textbox.borderbrushproperty.defaultmetadata.defaultvalue, which i did not manage to work.
Any ideas how to switch to default borderbrush? thank you.
Do you have to do it in code-behind? If not, you could use a Trigger which will only change the border color while the trigger condition is met.
<Style x:Key="MyTextBoxStyle" TargetType="{x:Type TextBox}">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=MyUserControl, Path=HasErrors}">
<Setter Property="BorderBrush" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
Why not just save the initial value at startup and use that? You should be able to use the system colors, but if you ever change the default color this will continue to work.
private Color _defBtnColor;
public MyUserControl()
{
_defBtnColor = someButton.Foreground;
}
private void SetBackToDefault()
{
someButton.Foreground = _defBtnColor;
}
Try:
control.BackColor = Color.FromKnownColor(KnownColor.Window);
For more information, see Color.FromKnownColor on MSDN.
Maybe I'm a little late to the party but I think you're asking how to change a color to the system default of control?
someControl.BackColor = SystemColors.Control;
or
sslEditMode.BackColor = SystemColors.ButtonFace;

WPF - Trigger not firing

I'm having an issue when trying to do something which should be as easy as. I've attempted to use a Trigger based on a DependencyProperty or a DataTrigger - I can't get either to work.
XAML for the trigger is:
<Style x:Key="FileWatchButton" BasedOn="{StaticResource {x:Type Button}}" TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="Main:Main.XmlFilesAvailableForLoading" Value="True">
<Setter Property="Background" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
And the associated code-behind is:
public static readonly DependencyProperty XmlFilesAvailableForLoadingProperty =
DependencyProperty.Register("XmlFilesAvailableForLoading", typeof(bool), typeof(Main));
public bool XmlFilesAvailableForLoading
{
get
{
try
{
return (bool)this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.DataBind,
(System.Windows.Threading.DispatcherOperationCallback)delegate { return GetValue(XmlFilesAvailableForLoadingProperty); },
XmlFilesAvailableForLoadingProperty);
}
catch (Exception)
{
return (bool)XmlFilesAvailableForLoadingProperty.DefaultMetadata.DefaultValue;
}
}
set
{
this.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.DataBind,
(System.Threading.SendOrPostCallback)delegate{ SetValue(XmlFilesAvailableForLoadingProperty, value); }, value);
}
}
Basically the dp is being set correctly by the presenter (it's based on a FileSystemWatcher class looking for one or more files) but the Trigger is not being fired. Is this a threading issue?
Thanks.
It's not clear if the code is complete, but it looks like the Property path in your trigger may be wrong. Does the button being styled have a Main property? I am guessing not; it looks like you are trying to trigger on a property of a different element, called Main -- is that right?
In any case, the namespace prefix is not required. If the button has a property named Main, then you can address this directly; if it doesn't, then the prefix won't help you.
My guess is that you probably need a DataTrigger whose binding refers to the Main element:
<local:Main Name="MyMain" ... /> <!-- this has the XmlFilesAvailableForLoading property -->
<DataTrigger Binding="{Binding XmlFilesAvailableForLoading, ElementName=MyMain}"
Value=True>
<Setter Property="Background" Value="Red" />
</DataTrigger>
On an unrelated note, you should have any non-boilerplate implementation in your DP getter and setter. Remember that the binding and styling system will bypass the getter and setter and talk directly to the underlying storage. So I'd strongly advise changing these back to just plain GetValue and SetValue calls.

Categories

Resources