|
I typically bind "Fill" or "ForeGround", etc. to an expression in the "view model" (=> ...) if it can vary from one object to the next; I use "styling" only when a group is all styled the same. (Brushes can be shared).
(UWP doesn't have XAML "data triggers" so I stopped thinking about them).
How do you reference a Path stored as a resource?
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
Ya, I'm going to. Ultimately it will be in a theme with data trigger to change the color for state, such as Enabled, Disabled, MouseOver, etc.
Thanks
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
FYI, here's what I came up with. Thanks for your help!
Control
public class MaroisPathImageButton : Button
{
#region CTOR
static MaroisPathImageButton()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MaroisPathImageButton), new FrameworkPropertyMetadata(typeof(MaroisPathImageButton)));
}
#endregion
#region Dependency Properties
#region DP Caption
public static readonly DependencyProperty CaptionProperty =
DependencyProperty.Register("Caption",
typeof(string),
typeof(MaroisPathImageButton),
new PropertyMetadata(""));
public string Caption
{
get { return (string)GetValue(CaptionProperty); }
set { SetValue(CaptionProperty, value); }
}
#endregion
#region DP PathData
public static readonly DependencyProperty PathDataProperty =
DependencyProperty.Register("PathData",
typeof(System.Windows.Media.Geometry),
typeof(MaroisPathImageButton),
new PropertyMetadata(null, new PropertyChangedCallback(OnPathDataChanged)));
public System.Windows.Media.Geometry PathData
{
get { return (System.Windows.Media.Geometry)GetValue(PathDataProperty); }
set { SetValue(PathDataProperty, value); }
}
private static void OnPathDataChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
MaroisPathImageButton control = (MaroisPathImageButton)d;
}
#endregion
#endregion
}
Theme
<!--PATH DATA-->
<Geometry x:Key="toolbarHomeButtonPathData">
M12 5.69L17 10.19V18H15V12H9V18H7V10.19L12 5.69M12 3L2 12H5V20H11V14H13V20H19V12H22
</Geometry>
<!BASE PATH IMAGE BUTTON STYLE>
<Style x:Key="pathImageButtonStyle"
TargetType="{x:Type mctrls:MaroisPathImageButton}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Height" Value="40"/>
<Setter Property="Width" Value="65"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid x:Name="Grid">
<Border x:Name="border"
Margin="2"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="0"
CornerRadius="3">
<StackPanel Orientation="Vertical">
<Path x:Name="path"
Width="20"
Height="20"
Data="{Binding PathData, RelativeSource={RelativeSource TemplatedParent}}"
Fill="{StaticResource Button.Normal.Background}"
Stretch="Uniform"/>
<TextBlock Grid.Row="1"
Grid.Column="0"
x:Name="caption"
Text="{Binding Caption, RelativeSource={RelativeSource TemplatedParent}}"
Foreground="{StaticResource Button.Normal.Background}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="0,0,0,2"/>
</StackPanel>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="path" Property="Fill" Value="{StaticResource Button.Normal.Foreground}" />
<Setter TargetName="caption" Property="Foreground" Value="{StaticResource Button.Hover.Foreground}" />
<Setter TargetName="border" Property="BorderBrush" Value="{StaticResource Button.Hover.Foreground}" />
<Setter TargetName="border" Property="BorderThickness" Value="1" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="path" Property="Fill" Value="{StaticResource Button.Disabled.Foreground}" />
<Setter TargetName="caption" Property="Foreground" Value="{StaticResource Button.Disabled.Foreground}" />
<Setter TargetName="border" Property="BorderBrush" Value="{StaticResource Button.Disabled.Foreground}" />
<Setter TargetName="border" Property="BorderThickness" Value="1" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!TOOLBAR HOME BUTTON STYLE>
<Style x:Key="toolbarHomeButtonStyle"
BasedOn="{StaticResource pathImageButtonStyle }"
TargetType="{x:Type mctrls:MaroisPathImageButton}">
<Setter Property="Caption" Value="Home"/>
<Setter Property="PathData" Value="{StaticResource toolbarHomeButtonPathData}"/>
</Style>
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
|
|
Something I have used in the past XAML Path Icons[^]. They allow you to download the XAML paths for icons which you can adjust as necessary.
|
|
|
|
|
OK so I got it from the MS Store on my PC. But I don't see it installed. How do I open this each time I want to use the icons?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
I normally just type XAML Path Icons in my window search bar. It opens from there for me.
|
|
|
|
|
My company has a product that runs on Windows, Android, and iOS. They want to define the app themes in json files so they can be shared across each app.
The only way I can see this working in Windows is to deserialize the json into a class and apply themes programmatically versus using theme dictionaries.
Anyone have any thoughts on this?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
modified 6-Mar-23 13:04pm.
|
|
|
|
|
I'm trying to create a Custom Control that will be a DropDown TreeView.
Basically I want to replace a comboboxe's control template with a treeview. I've tried different things, but here's what I have so far:
<Style TargetType="{x:Type local:MaroisDropDownTree}">
<pre>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Border Margin="2"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding BorderThickness}">
<TreeView ItemsSource="{Binding TreeData, RelativeSource ={RelativeSource TemplatedParent}}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
When I run it and drop it down, there's nothing there.
Can someone please point me in the right direction?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
|
How would you implement this as a custom control? I know the ControlTemplate would have to be overridden, but I'm fuzzy on how to do it.
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
I've implemented "tree views" using a user control "around" a ListView. All my user control revolve around something; nothing ever so special that it required a "custom control" (which is more complicated).
For a tree view - list view, each item is a usercontrol that can "indent" or "hide" itself (when expanding or collapsing). The item's user control has it's own data template; and that's how you can have every every item (level) look different by selectively exposing different parts of the same UC type.
All that's required of the item "data container" is a level number and an "expanded / collapsed" indicator; the level number is used to compute the indent (a Margin or some other "empty" object with length). The items are of course loaded in the proper sequence (hierarchy / BOM). A selection change handler can identify what level and "node" is being accessed. An expand / collapsed method keys off the current selected item and just travels the sequence below that depth.
I also added parent and child pointers (based on my needs). And added drag and drop from the (listview) tree view. On the surface, you can't tell it's a listview. Once you build one, only the item data template changes for the next "tree view".
The "drop down" could be the tree view inside a ScrollViewer, inside an Expander. Or a popup. What ever works best.
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
As the title says, I am facing an issue when the styles of a window element are coming from an external resource dictionary which is included into a .dll reference of my project. The problem is that styles aren't apply in design mode!!!
To be more specific...
I have create a (.NET 4.8 Framework) WPF control library project which, among other stuff, includes some resource dictionary (.xaml) files with styles. To use these styles into a (.NET 4.8 Framework) WPF application project, as far as I know, I can use two ways...
WAY ONE: ( [^]Example )
■ Into the solutions of my application project I add my control library as a new project.
■ I go into my application project and I add a reference that points to my control library project (.csproj) file.
■ I add the .xaml file from my control library project into the App.xaml file of my application project as merged dictionary.
■ And finally, I give the desired style to my window element.
Using way one it works fine, in design mode too, but what if, for various obvious reasons, I want to give my control library to someone as a .dll file? Then, as far as I know, I have to use the second way...
WAY TWO: ( [^]Example )
■ Without to add my control library as a new project into the solution of my application project, I go to my application project and I add a reference that points to the .dll file of my control library.
■ I add the .xaml file from my control library project into the App.xaml file of my application project as merged dictionary.
■ And finally, I give the desired style to my window element.
But, using way two, styles are applying only when I run the program and not in design mode!!! And this happens only for window elements!!! As you can see if you run the code of "Way Two" example, the grid gets the given style even in design mode. The problem is with the window element!!!
I made this question in Stackoverflow too and I got [^]this answer which doesn't work for me. [^]Here is an example code I tried based on above answer...
I also made the same question here, in Quick Answers section and I got [^]this answer which also doesn't work for me. [^]Here is an example code I tried based on above answer.
In both cases I still have the same problem. The styles of the window element are not applied in design mode!!!
Can someone help me to solve this issue please?
PS: I am working on Window 10 machine, using Visual Studio 2022 version 17.5.0 and my WPF projects based on .NET 4.8 Framework.
Thank you for your time!!!
|
|
|
|
|
|
@Graeme_Grand [^] who wrote this [^] and then he deleted it!!!
/////
Normally I wouldn't go into this process but after this arrogant irony "I don't think that it is so much as the solution does not work, but who is using it" I will.
Υour solution doesn't work for me because into your examples you load the library as .csproj and not as .dll file. You can download [^]this (.NET Framework 4.8) project so to see what I mean. Or you can recreate the whole thing by your self using .NET Framework 4.8 and loading the library as .dll file. And not as a project.
If you make it work that way I will humbly apologize, otherwise you will have to. Of course you can just ignore me. The only thing that isn't accepted is the irony and the arrogance... This kind of behavior is shameful to anyone!!!
modified 24-Feb-23 5:57am.
|
|
|
|
|
@Graeme_Grand [^]
/////
Oh, I missed the point... And it won't work... Well I have some "bad news". After some tests, it is working, in a way!!! Both, in design time and run time too. Even if I reference my library as .dll to a separate project. But, for some reason that I can't understand for now (since I'm new to WPF) I had to change the target type of <Style x:Key="MainWindow_Style" TargetType="{x:Type Window}"> from Window to Control . Of course I can't use it like this because I'll loose the ability to style properties of Window element. So what I am trying to find right now is "why is this happening?". Why this issue is happening only with Window element?
modified 24-Feb-23 7:51am.
|
|
|
|
|
@Graeme_Grand [^]
/////
Yes, I have a 100% working solution right now and I'll post it as soon as I get back the reputation points that were taken away from me for daring to be right!!!
PS: Some people in here need a psychiatric follow-up. Frankly...
modified 24-Feb-23 7:52am.
|
|
|
|
|
I'm trying to create a simple log in window. The Sign In button does not get enabled. The CanExecuteChange fires on startup, but never after that.
You can see that I'm using the Community Toolkit. I've also tried the RelayCommand in my own framework. Neither work. I have also tried
CommandManager.InvalidateRequerySuggested();
in the UserName and Password properties.
Here's the Sign In button
<Button Grid.Row="7"
Grid.Column="0"
Content="Sign In"
Command="{Binding SignInCommand}"
Margin="0,0,0,0"/>
Here's the View Model
using CommunityToolkit.Mvvm.Input;
using Marois.Framework.Core.Shared;
using System.Windows.Input;
namespace Jayhawk.UI.WPF.ViewModels
{
public class LoginViewModel : _DialogViewModelBase
{
#region Private Fields
private readonly IEventAggregator _eventAggregator;
#endregion
#region Properties
private string? _UserName;
public string? UserName
{
get { return _UserName; }
set
{
SetProperty(nameof(UserName), ref _UserName, value);
}
}
private string? _Password;
public string? Password
{
get { return _Password; }
set
{
SetProperty(nameof(Password), ref _Password, value);
}
}
private bool _IsRememberMeChecked;
public bool IsRememberMeChecked
{
get { return _IsRememberMeChecked; }
set
{
SetProperty(nameof(IsRememberMeChecked), ref _IsRememberMeChecked, value);
}
}
private bool _IsLoggingIn;
public bool IsLoggingIn
{
get { return _IsLoggingIn; }
set
{
SetProperty(nameof(IsLoggingIn), ref _IsLoggingIn, value);
}
}
#endregion
#region Commands
private ICommand? _SignInCommand;
public ICommand? SignInCommand
{
get
{
if (_SignInCommand == null)
_SignInCommand = new RelayCommand(SignInExecuted, SignInCanExecute);
return _SignInCommand;
}
}
#endregion
#region CTOR
public LoginViewModel()
{
}
#endregion
#region Private Methods
private bool SignInCanExecute()
{
return !string.IsNullOrEmpty(UserName) && !string.IsNullOrEmpty(Password);
}
private void SignInExecuted()
{
IsLoggingIn = true;
}
#endregion
}
}
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Looking at the source code for CommunityToolkit.Mvvm.Input.RelayCommand [^], it doesn't use the CommandManager at all. You need to explicitly call the NotifyCanExecuteChanged method[^] instead.
NB: That SetProperty method looks odd - any relatively recent framework would use [CallerMemberName] so that you don't need to pass the name of the property:
protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (Equals(storage, value)) return false;
storage = value;
OnPropertyChanged(propertyName);
return true;
}
public string? UserName
{
get { return _UserName; }
set { SetProperty(ref _UserName, value); }
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
hi guys, how to set the icon for output result(.exe) in vs2022 ? thanks.
|
|
|
|
|
Try Project -> Properties.
|
|
|
|
|
|
I'm trying to create a ListBox, with it's ItemTemplate being an expander, which itself has a list in it.
Here's a pic of what I'm trying to accomplish. Pic
I added colors around each item to highlight what's happening.
Here's the XAML
<ListBox Grid.Row="2"
Grid.Column="1"
x:Name="outerList"
Margin="2,2,2,2"
Background="Transparent"
ItemsSource="{Binding RecentItemSections}"
SelectedItem="{Binding SelectedRecentItemSection}"
HorizontalAlignment="Stretch"
BorderBrush="Yellow"
BorderThickness="2">
<ListBox.ItemTemplate>
<DataTemplate>
<Expander IsExpanded="{Binding IsSectionExpanded}"
x:Name="expander"
HorizontalAlignment="Stretch"
BorderBrush="Red"
BorderThickness="2">
<Expander.Header>
<TextBlock Text="{Binding SectionName}"
Foreground="White"
Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type ListBoxItem}}, Path=ActualWidth}"/>
</Expander.Header>
<ListBox ItemsSource="{Binding RecentItems}"
BorderBrush="Green"
BorderThickness="5"
Margin="2,0,20,0">
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="MediumAquamarine"
BorderThickness="2">
<StackPanel Orientation="Vertical"
HorizontalAlignment="Stretch">
<TextBlock Text="{Binding ItemName}"
FontSize="12"
Margin="2"/>
<TextBlock Text="{Binding ItemLocation}"
FontSize="10"
Margin="2,0,2,2"/>
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Expander>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
As you can see in the pic, the Expander's header is off the right side of the listbox item.
How can I get the expander to fit inside its parent, the ListBox?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
You should know what the maximum header width will be; set the .Width accordingly. (The framework doesn't know beforehand).
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|