|
What's wrong with binding the IsEnabled property on the Hyperlink to a property on your view-model?
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
It would need to be bound to a property on the entity - except there is no entity. I'm loading the combo box with enums.
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Use a DataTemplateSelector as the ComboBox.ItemTemplateSelector .
The SelectTemplate() method will be passed each item, (the enum in your case).
Select a data template specific to each case you want.
"Fairy tales do not tell children the dragons exist. Children already know that dragons exist. Fairy tales tell children the dragons can be killed."
- G.K. Chesterton
|
|
|
|
|
I've got Row Details section in a DataGrid. The DataGrid's width is set to 1500, yet the row details content stretches off the right side of the grid. Here's all the XAML.
Here's a screen shot
How do I make the Row Details content wrap?
<DataGrid x:Name="seqSheetDataGrid"
Grid.Row="1"
Grid.Column="0"
ItemsSource="{Binding SequenceSheets, Mode=TwoWay}"
SelectedItem="{Binding SelectedSequenceSheet, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
RowDetailsVisibilityMode="Visible"
behaviors:SortDescriptionBehavior.Property="SeqSheetGridSortDescription"
MaxWidth="1700">
<DataGrid.Resources>
<Style TargetType="DataGridCell" BasedOn="{StaticResource dataGridCellStyle}">
<Style.Triggers>
<DataTrigger Binding="{Binding Status}" Value="Removed">
<Setter Property="FontStyle" Value="Italic" />
<Setter Property="Foreground" Value="LightGray" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow"
BasedOn="{StaticResource dataGridRowStyle}">
<Setter Property="BorderBrush" Value="SteelBlue" />
<Setter Property="BorderThickness" Value="0,0,0,1" />
<Setter Property="Height" Value="{x:Static sys:Double.NaN}"/>
</Style>
</DataGrid.RowStyle>
<DataGrid.Style>
<Style TargetType="DataGrid"
BasedOn="{StaticResource dataGridStyle}">
<Setter Property="IsReadOnly" Value="True" />
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding AreFieldsEnabled}" Value="True" />
<Condition Binding="{Binding Job.ContractDate, Converter={StaticResource IsNotNullConverter}}" Value="True" />
<Condition Binding="{Binding Job.ContractDateInitials, Converter={StaticResource IsNotNullConverter}}" Value="True" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="IsReadOnly" Value="False" />
</MultiDataTrigger.Setters>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</DataGrid.Style>
<DataGrid.Columns>
<DataGridTextColumn Header="Sequence"
Binding="{Binding Sequence, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Width="120"
SortDirection="Ascending"
SortMemberPath="Sequence"
IsReadOnly="True"/>
<DataGridTextColumn Header="Lot's / Bldgs"
Binding="{Binding Lot, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Width="120"
SortMemberPath="Lot"
IsReadOnly="True"/>
<DataGridTextColumn Header="Plan"
Binding="{Binding Plan, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Width="120"
SortMemberPath="Plan"
IsReadOnly="True"/>
<DataGridTextColumn Header="Square Feet"
Binding="{Binding SquareFeet, StringFormat={}{0:#,#}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Width="120"
HeaderStyle="{StaticResource dataGridRightAlignColHeaderStyle}"
SortMemberPath="SquareFeet"
IsReadOnly="True">
<DataGridTextColumn.ElementStyle>
<Style>
<Setter Property="TextBlock.TextAlignment" Value="Right" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Header="Elevation"
Binding="{Binding Elevation, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Width="120"
SortMemberPath="Elevation"
IsReadOnly="True"/>
<DataGridComboBoxColumn Header="Garage Type"
SelectedValueBinding="{Binding GarageTypeId}"
SelectedValuePath="Id"
DisplayMemberPath="Caption"
Width="120"
SortMemberPath="GarageTypeId"
IsReadOnly="True">
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="ItemsSource" Value="{Binding ElementName=jobView, Path=DataContext.GarageTypes}" />
</Style>
</DataGridComboBoxColumn.ElementStyle>
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="ItemsSource" Value="{Binding ElementName=jobView, Path=DataContext.GarageTypes}" />
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
<DataGridTextColumn Header="Enhanced Rear"
Binding="{Binding EnhancedRear, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource TrueFalseYesNoConverter}}"
Width="120"
SortMemberPath="EnhancedRear"
IsReadOnly="True"/>
<DataGridTextColumn Header="Enhanced Left"
Binding="{Binding EnhancedLeft, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource TrueFalseYesNoConverter}}"
Width="120"
SortMemberPath="EnhancedLeft"
IsReadOnly="True"/>
<DataGridTextColumn Header="Enhanced Right"
Binding="{Binding EnhancedRight, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource TrueFalseYesNoConverter}}"
Width="120"
SortMemberPath="EnhancedRight"
IsReadOnly="True"/>
<DataGridTextColumn Header="Address"
Binding="{Binding Address, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Width="400"
SortMemberPath="Address"
IsReadOnly="True"/>
<DataGridTextColumn Header="Status"
Binding="{Binding Status, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Width="150"
SortMemberPath="Status"
IsReadOnly="True"/>
</DataGrid.Columns>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Options: "
FontWeight="Bold"
Margin="2" />
<TextBlock Text="{Binding OptionsText}"
TextWrapping="Wrap"
Margin="2" >
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding Status}" Value="Removed">
<Setter Property="FontStyle" Value="Italic" />
<Setter Property="Foreground" Value="LightGray" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</StackPanel>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
modified 29-Jul-21 13:48pm.
|
|
|
|
|
Is it possible to get the MainWindow from the exeucting assembly?
I am opening a dialog contained in another assembly and in that dialog I want to set the Owner to the Main Window of my executing app.
I know in the dialog I can do
var callingAssembly = Assembly.GetCallingAssembly();
which gives me the assembly of my main app. But Can I then somehow get access to that assembly's Application.Current.MainWindow?
What I'd really like, in my dialog, is something like this:
public MyDialog()
{
var window =
this.Owner = window;
}
Thanks!
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
modified 23-Jul-21 15:42pm.
|
|
|
|
|
Assuming you're not using a separate AppDomain to load the assembly, Application.Current.MainWindow should still work from the other assembly.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
OK, that worked. Thanks
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
|
|
Slacker007 wrote: Not sure why you would not use Visual Studio Community Edition to manage/edit your WPF files and projects.
Perhaps Mike is secretly part of a large, enterprise development team.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
What I'm looking for is a control I can slip into my app. Guess I didn't make that plain.
The less you need, the more you have.
Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?
JaxCoder.com
|
|
|
|
|
Sorry, Mike. I did not notice.
|
|
|
|
|
Looks like the SmithHtmlEditor project has moved to GitHub:
GitHub - adambarath/SmithHtmlEditor: The source code is about html editor usage in WPF application.[^]
It doesn't seem to have much detail there, and is still pointing to the (now defunct) CodePlex archive for more information. But the GitHub version seems to have been updated more recently.
There don't seem to be a huge number of other options - there's this one[^] from 2015, and this one[^], also from 2015, but beyond that Google is only suggesting commercial products.
I've not tried it, but you might have better luck embedding a WebView2[^] control and using a Javascript HTML editor.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Thanks Richard,
I considered the CodeProject one but settled on the smithhtmleditor. Seems to be working Ok, a little quirky with fonts but other than that fairly easy to use. All I need is some basic editing for keeping notes in the app I'm working on.
The less you need, the more you have.
Even a blind squirrel gets a nut...occasionally.
JaxCoder.com
|
|
|
|
|
I'm working on a WPF app that we now want to have a 'Test Mode'.
Right now, I have an 'IsTestMode' property in the app.config. If I set it to True, then the login window's border is red, and there's a red TEST MODE banner across the top of the main window. The Test Mode copy is installed in a different location then the production copy.
In the code behind of the Main Window I have:
Uri iconUri = null;
if (AppCore.IsTestMode)
{
iconUri = new Uri("my_test.ico", UriKind.Relative);
}
else
{
iconUri = new Uri("my.ico", UriKind.Relative);
}
this.Icon = BitmapFrame.Create(iconUri);
This changes the Taskbar Icon, not the desktop icon
This all works fine.
Now I want to add an installer project, but I'm stuck on how to make the Test Mode changes during installation. I'd like to do the following during installation and not let the user change them:
- Set the installation location
- Set the IsTestMode setting
- Change the desktop icon.
Can anyone shed some light on how to do this?
Thanks
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
modified 19-Jul-21 15:14pm.
|
|
|
|
|
I have a user control with a custom Routed Event. I'm trying to pass event args:
public class NavigationViewFilterEventArgs : RoutedEventArgs
{
public List<LookupEntity> StatusFilters { get; private set; }
public List<LookupEntity> FilterItems { get; private set; }
public NavigationViewFilterEventArgs(RoutedEvent e, List<LookupEntity> statusFilters, List<LookupEntity> filterItems) :
base(e)
{
StatusFilters = statusFilters;
FilterItems = filterItems;
}
}
Here's the UserControl code behind:
public static readonly RoutedEvent FilterExecutedEvent =
EventManager.RegisterRoutedEvent("FilterExecuted",
RoutingStrategy.Bubble,
typeof(RoutedEventHandler),
typeof(NavigationView));
public event RoutedEventHandler FilterExecuted
{
add { AddHandler(FilterExecutedEvent, value); }
remove { RemoveHandler(FilterExecutedEvent, value); }
}
private void RaiseFilterExecutedEvent()
{
var args = new NavigationViewFilterEventArgs(FilterExecutedEvent, StatusFilters, FilterItems);
RaiseEvent(args);
}
The control is on the Main Window:
<ctrls:NavigationView Grid.Row="7"
Caption="Companies"
StatusFilters="{Binding DataContext.CompanyStatusFilterItems,
ElementName=window, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="FilterExecuted">
<i:InvokeCommandAction Command="{Binding DataContext.CompanyFilterExecutedEventCommand,
ElementName=window}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ctrls:NavigationView>
And finally the handler in the Main Window view model:
private ICommand _CompanyFilterExecutedEventCommand;
public ICommand CompanyFilterExecutedEventCommand
{
get
{
if (_CompanyFilterExecutedEventCommand == null)
_CompanyFilterExecutedEventCommand = new RelayCommand<NavigationViewFilterEventArgs>(p => CompanyFilterExecutedEventExecuted(p), p => CompanyFilterExecutedEventCanExecute());
return _CompanyFilterExecutedEventCommand;
}
}
private bool CompanyFilterExecutedEventCanExecute()
{
return true;
}
private void CompanyFilterExecutedEventExecuted(NavigationViewFilterEventArgs args)
{
}
When I run this and click the button, the event reaches the Main Window VM's CompanyFilterExecutedEventExecuted method, but the param is always null.
I could use some help here.
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
|
I want to change the combobox's backgound but when set the default background it doesn't change, I want to change the background color in the code behind, thank!
|
|
|
|
|
Hi!
Sorry for weird subject but was a bit unsure on what to call it.
Anyway, I have a WPF-form where I have some items below a textbox. I want the textbox to fill up the grid above the bottom controls but leave space for them.
<Window x:Class="SMS_Sender_3._0.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SMS_Sender_3._0"
mc:Ignorable="d"
Title="SMS Sender 3.0" Height="350" Width="525">
<Grid>
<Border Margin="8">
<StackPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Phone:" />
<TextBox Grid.Column="1" />
</Grid>
<TextBlock Text="Message:" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="225" />
</Grid.RowDefinitions>
<TextBox Grid.Column="1" />
</Grid>
<Grid Margin="0,3,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="150" />
<ColumnDefinition Width="60" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Mall:" />
<ComboBox Grid.Column="1" />
<TextBlock Margin="5,0,0,0" Grid.Column="2" Text="0/160(1)" />
<Button Grid.Column="3" HorizontalAlignment="Right" Content="_Send" Width="100" />
</Grid>
<Grid Margin="0,3,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Type:" />
<ComboBox Grid.Column="1" HorizontalAlignment="Left" Width="150" />
</Grid>
</StackPanel>
</Border>
</Grid>
</Window>
As it is now, the textbox will change it width but not it's height, due to it being set to 225 in the grid definition. However, I am unsure how to set the grid so that it will take up the space but leave the bottom controls visible. Basically I want it to be as it is now but able to resize.
I am thankfull for any suggestions.
Have a nice day!
I am using JetBrains Rider!
|
|
|
|
|
|
When you put Grids in a StackPanel, the Grids "lose" their "star" (*) qualities since StackPanel do not fill available space.
You should put your Grids in a parent Grid instead of a StackPanel (if you want to make the most of "stretching").
I typically start everything with "*" or Auto; only afterwards do I (rarely) touch up with explicit widths or heights.
It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it.
― Confucian Analects: Rules of Confucius about his food
|
|
|
|
|
The purpose of this code is open image file in a page and display it in another page.
I had tried set ViewModel by using Singleton Pattern, but it didn't work....
If I integrate to one View, it can display the image correctly. But I need to separate the views.
I have no idea what's wrong in this MVVM code....and how to fix it?
Please point me how can I do or let me know what keyword I can search the toturial/sample.
Thank you all.
--
The OpenFile button is on DisplayControlView and display on DisplayView.
The View Schema is as below:
MainWindow.xaml (window)
|
|__ReviewView.xaml (page)
|
|__DisplayControlView.xaml (page)
|
|__DisplayPanelView.xaml (page)
|
|__DisplayView.xaml (page)
--
DisplayControlView.xaml
<Page.DataContext>
<vm:DisplayViewModel/>
</Page.DataContext>
...
<Button x:Name="btnDpOpen" Style="{DynamicResource ButtonStyle}" Width="120" Command="{Binding OpenFile}">
...
--
DisplayView.xaml
<Page.DataContext>
<vm:DisplayViewModel/>
</Page.DataContext>
...
<Image x:Name="imgDisplayView" Source="{Binding ImagePath}">
<Image.RenderTransform>
<TransformGroup>
<TranslateTransform/>
<RotateTransform/>
<ScaleTransform/>
</TransformGroup>
</Image.RenderTransform>
</Image>
...
--
DisplayViewModel.cs
class DisplayViewModel : ViewModelBase
{
private DisplayImageModel image { get; set; }
private ObservableCollection<DisplayImageModel> imagelist = new ObservableCollection<DisplayImageModel>();
public ObservableCollection<DisplayImageModel> ImageList
{
get { return imagelist; }
set
{
imagelist = value;
OnPropertyChanged();
}
}
public string ImagePath
{
get { return image.Path; }
set
{
if (image.Path != value)
{
image.Path = value;
OnPropertyChanged();
}
}
}
public DisplayViewModel()
{
image = new DisplayImageModel();
ImagePath = @"C:\Users\oscartsai\Desktop\lenna.png";
}
public bool CanExecute()
{
return true;
}
public RelayCommand OpenFile
{
get { return new RelayCommand(openFile, CanExecute); }
}
private void openFile()
{
string[] picExtName = new string[] { ".PNG", ".JPG", "JEPG", "BMP" };
OpenFileDialog dlgOpenFile = new OpenFileDialog()
{ Filter = "Picture|*.jpg;*.jpeg;*.bmp;*.png|All File|*.*" };
if (dlgOpenFile.ShowDialog() != true)
{
return;
}
if (picExtName.Any(System.IO.Path.GetExtension(dlgOpenFile.FileName).ToUpper().Contains))
{
ImagePath = dlgOpenFile.FileName;
OnPropertyChanged();
}
}
}
--
ViewModelBase.cs
public abstract class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void SetValue<T>(ref T property, T value, [CallerMemberName] string propertyName = null)
{
if (property != null)
{
if (property.Equals(value))
{
return;
}
}
property = value;
OnPropertyChanged(propertyName);
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
--
RelayCommond.cs
public class RelayCommand : ICommand
{
readonly Func<bool> _canExecute;
readonly Action _execute;
public RelayCommand(Action execute) : this(execute, null)
{
}
public RelayCommand(Action execute, Func<bool> canExecute)
{
_execute = execute ?? throw new ArgumentNullException("execute");
_canExecute = canExecute;
}
public event EventHandler CanExecuteChanged
{
add
{
if (_canExecute != null) CommandManager.RequerySuggested += value;
}
remove
{
if (_canExecute != null) CommandManager.RequerySuggested += value;
}
}
[DebuggerStepThrough]
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute();
}
public void Execute(object parameter)
{
_execute();
}
}
|
|
|
|
|
You've got a .Contains function with no parameter.
if (picExtName.Any(System.IO.Path.GetExtension(dlgOpenFile.FileName).ToUpper().Contains))
It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it.
― Confucian Analects: Rules of Confucius about his food
|
|
|
|
|
It uses String[].Any() to indicate the parameter.
The problem is it can't display selected image file on DisplayView (page)....
As my original post mention, all the same code can work well in one ViewModel and one View.
When I separate the code to one ViewModel and 3 Views, it can not work as my expected.
It just can show open dialog for selecting file, but display nothing after selection.
I think the problem will be the operation on one View(DisplayControlView) can not effect another View(DisplayView)
|
|
|
|
|
I use code-behind to load images; that works.
I also hook up the "ImageFailed" event; then you know why it's not working (somewhat).
(MVVM has too much "indirection" for my brain).
It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it.
― Confucian Analects: Rules of Confucius about his food
|
|
|
|
|