|
Prism isn't Microsoft offering. It's maintained by Brian Lagunas and Dan Siegel. Both are MVPs, but work for other companies.
|
|
|
|
|
So, the fact that someone else now maintains it negates my opinion even though Microsoft originated it? Run with that.
"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
|
|
|
|
|
It has been so long away from the P&P camp that Microsoft's influence on it has long been expunged. The simple fact is, Microsoft has their own MVVM offering which has nothing to do with Prism. Your statement implied that Prism was a Microsoft offering and it hasn't been for a long time so if you are pushing someone to Microsoft's offering, at least make sure it is Microsoft that is offering it.
|
|
|
|
|
I have the following code in Code-Behind section of my WPF MVVM:
public EquipmentIdentity()
{
InitializeComponent();
EquipmentIdentityViewModel eivm = new EquipmentIdentityViewModel();
DataContext = eivm;
dataPager.OnDemandLoading += dataPager_OnDemandLoading;
}
private void dataPager_OnDemandLoading(object sender, Syncfusion.UI.Xaml.Controls.DataPager.OnDemandLoadingEventArgs args)
{
}
How can I remove this event handling from Code-Behind and take it to the ViewModel?
When I use dataPager.OnDemandLoading += dataPager_OnDemandLoading; in ViewModel it shows this error:
Quote: System.NullReferenceException: 'Object reference not set to an instance of an object.'
|
|
|
|
|
View models are about "data"; not "behavior".
mvc - Should MVVM models have behaviour? - Software Engineering Stack Exchange
"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
modified 17-Jul-22 12:22pm.
|
|
|
|
|
Hello everyone , I need your help , how to get dicom tags with wpf and openFileDialog
|
|
|
|
|
Reading DICOM file tags has nothing to do with WPF or the OpenFile dialog. WPF is a presentation (UI) framework, and an OpenFile dialog just gets a filepath from the user.
Reading the tag data is just straight up reading a file. There's plenty of info on the web on it. You just have to search for "C# read DICOM tags[^]" and start reading.
|
|
|
|
|
Just starting out in learning VS, C# and Xaml.
I am much older than most on here...I am betting anyway.
EE-PE that has folded a 20+ year Consulting Engineering business and trying to see if somehow I can do something in programming. I have struggled through and have a desktop app completed but have NO idea what is next.
Do a need to get a business certificate of some type so the app can load on others computers ?
Do I search out companies that market third party development ?
Do I partner with another developer to handle the marketing aspect ?
First choice of mine would be to find a Cleveland Ohio developer I could actually talk with, but have had zero success in this path.
modified 7-Jul-22 21:01pm.
|
|
|
|
|
Or you can put it in the Microsoft store.
Publish traditional desktop apps through Microsoft Store | Microsoft Developer
"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
|
|
|
|
|
Thank you for taking the time to respond.
Quickly looking over the link brings up even more questions.
Appears my weak general knowledge will keep this just a hobby.
modified 7-Jul-22 21:01pm.
|
|
|
|
|
I am creating a Custom Control and in the control template I have a TreeView class in it.
<Style TargetType="{x:Type local:MyControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MyControl}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<TreeView ItemsSource="{Binding TreeDataItems, RelativeSource={RelativeSource TemplatedParent}}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:TreeItem}" ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Path=Caption}" />
</HierarchicalDataTemplate>
</TreeView.Resources>
<i:Interaction.Triggers>
<i:EventTrigger EventName="TreeViewItem.Expanded">
<i:InvokeCommandAction Command="{Binding TreeItemExpandedCommand, RelativeSource={RelativeSource TemplatedParent}}"
CommandParameter="{Binding}">
</i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</TreeView>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
In the code behind I have
private ICommand _TreeItemExpandedCommand;
public ICommand TreeItemExpandedCommand
{
get
{
if (_TreeItemExpandedCommand == null)
_TreeItemExpandedCommand = new RelayCommand<object>(p => TreeItemExpandedExecuted(p));
return _TreeItemExpandedCommand;
}
}
private void TreeItemExpandedExecuted(object args)
{
}
When I expand a node nothing happens. There are no binding errors, and the Command's getter fires when it starts, but the TreeItemExpandedExecuted never fires.
I tried using the event itself:
<TreeView TreeViewItem.Expanded="TreeViewItem_Expanded">
...
</TreeView/>
and
private void TreeViewItem_Expanded(object sender, RoutedEventArgs e)
{
TreeViewItem tvi = e.OriginalSource as TreeViewItem;
if (tvi != null)
{
}
}
But still nothing.
I'm guessing this has something to do with this all being in a ControlTemplate. Anyone see what's wrong here?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
I have a DataGrid bound to a list of models. On the ViewModel is a property called AreFieldsEnabled. When the user clicks Edit the it sets AreFieldsEnabled to true and the datagrid becomes enabled/
I have this style
<Style x:Key="dataGridCurrencyCellStyle"
BasedOn="{StaticResource dataGridCellStyle}"
TargetType="{x:Type DataGridCell}">
<Setter Property="Width" Value="75"/>
<Setter Property="TextBlock.TextAlignment" Value="Left"/>
<Setter Property="TextBlock.Text" Value="{Binding StringFormat=C}"/>
<Setter Property="IsEnabled" Value="{Binding DataContext.AreFieldsEnabled, ElementName=budgetControl}"/>
</Style>
What I need do now is a change it to a MultiTrigger. On the model is a bool property called IsCellEnabled which I set programmatically when loading the data.
<Style x:Key="dataGridCurrencyCellStyle"
BasedOn="{StaticResource dataGridCellStyle}"
TargetType="{x:Type DataGridCell}">
<Setter Property="Width" Value="75"/>
<Setter Property="TextBlock.TextAlignment" Value="Left"/>
<Setter Property="TextBlock.Text" Value="{Binding StringFormat=C}"/>
<Setter Property="IsEnabled" Value="False"/>
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="AreFieldsEnabled" Value="True" />
<Condition Property="IsCellEnabled " Value="True" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="IsEditing" Value="True" />
</MultiTrigger.Setters>
</MultiTrigger>
</Style.Triggers>
</Style>
Now, both conditions are wrong and won't compile.
So, the AreFieldsEnabled property is on the ViewModel. The IsCellEnabled property is on the Model bound to the grid.
What's the right way to do this?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
modified 12-Apr-22 13:25pm.
|
|
|
|
|
Use a MultiDataTrigger when the conditions depend on a binding rather than the styled control's properties.
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding DataContext.AreFieldsEnabled, ElementName=budgetControl}" Value="True" />
<Condition Binding="{Binding IsCellEnabled}" Value="True" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="IsEditing" Value="True" />
</MultiDataTrigger.Setters>
</MultiDataTrigger>
</Style> MultiDataTrigger Class (System.Windows) | Microsoft Docs[^]
WPF MultiTrigger and MultiDataTrigger - The complete WPF tutorial[^]
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Thanks. That only partly fixed it
<Style x:Key="dataGridCurrencyCellStyle"
BasedOn="{StaticResource dataGridCellStyle}"
TargetType="{x:Type DataGridCell}">
<Setter Property="Width" Value="75"/>
<Setter Property="TextBlock.TextAlignment" Value="Left"/>
<Setter Property="TextBlock.Text" Value="{Binding StringFormat=C}"/>
<Setter Property="IsEnabled" Value="False"/>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding DataContext.AreFieldsEnabled, ElementName=budgetControl}" Value="True" />
<Condition Binding="{Binding IsCellEnabled}" Value="True" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="IsEnabled" Value="True" />
</MultiDataTrigger.Setters>
</MultiDataTrigger>
</Style.Triggers>
</Style>
The 2nd condition with the IsCellEnabled isn't finding the model the row is bound to. Not sure how to reference that from this style. I get a binding error "BindingExpression path error: 'IsCellEnabled' property not found on 'object' ''DataRowView'"
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
I'm still stuck on this. I can't seem to get the second trigger condition to bind correctly. How would I bind the condition to the IsCellEnabled property on the model?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
modified 13-Apr-22 14:13pm.
|
|
|
|
|
Kevin Marois wrote: 'IsCellEnabled' property not found on 'object' ''DataRowView'"
You're not binding to the model; you're binding to a DataView .
You could try {Binding [IsCellEnabled]} , assuming that is a column in your view.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
I am generating a datagrid on the fly at runtime. See this pic .
I am generating a Data Table, and the go through each column of the table and create DataGridColumns. The first column, the Type, is read only. The rest are editable and will accept money values.
I am trying to apply the cell style in code behind:
foreach (string item in columnNames)
{
Binding binding = new Binding(item);
string styleName = "";
if (item == "Type")
{
binding.Mode = BindingMode.OneTime;
styleName = "budgetGridCellStyle";
}
else
{
binding.Mode = BindingMode.TwoWay;
binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
styleName = "dataGridCurrencyCellStyle";
}
var style = Application.Current.FindResource(styleName) as Style;
var col = new DataGridTextColumn()
{
Header = item,
Binding = binding,
Visibility = Visibility.Visible,
CellStyle = style
};
DataGridColumns.Add(col);
}
Here is the DataGridCellStyle
<Style x:Key="dataGridCurrencyCellStyle"
BasedOn="{StaticResource dataGridCellStyle}"
TargetType="{x:Type DataGridCell}">
<Setter Property="Width" Value="75"/>
<Setter Property="TextBlock.TextAlignment" Value="Right"/>
<Setter Property="TextBlock.Text" Value="{Binding StringFormat={}{0:0.##}}"/>
<Setter Property="IsEnabled" Value="{Binding DataContext.AreFieldsEnabled, ElementName=budgetControl}"/>
</Style>
Yet, AFTER I save changes, the cells end up with 4 decimal places.
Anyone have any ideas on how to fix this?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
modified 7-Apr-22 11:25am.
|
|
|
|
|
Kevin Marois wrote: The first column, the Type, is read only. The rest are read only
Unless you meant to say that all columns are read-only, I suspect the rest are editable.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Yup, you're right. I corrected it.
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
BindingBase.StringFormat Property (System.Windows.Data) | Microsoft Docs
"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
|
|
|
|
|
Thanks for the reply, but I don't see how that solves the issue
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
I got a new UI change in the app where a given UI (it contains a tree-list-view) can now be split (very much like VS text editor), in 2 identical view (same view model, same view template).
I need to track which of the 2 split view is the "current one", so if the view model drive an edit session of one of the cell, only the "current split view" will start editing.
Now the question is.. how do I know which one is the "current view"?!
EDIT, SOLVED IT!
Using the power of friendship! And, erm... MultiBinding , against both model.IsEditing and "is in active view ".
modified 5-Apr-22 21:23pm.
|
|
|
|
|
As part of my own framework I am developing Service and View Model Locators. Both are done, but I have one problem.
Here's what I have so far:
Interface
public interface IViewModelLocator
{
object Get<T>();
void Register(Type viewType, object viewModel);
}
View Model Locator Class
public class ViewModelLocator : IViewModelLocator
{
private IDictionary<Type, object> _storage;
public ViewModelLocator()
{
_storage = new Dictionary<Type, object>();
}
public object Get<T>()
{
if (_storage.ContainsKey(typeof(T)))
{
return _storage.FirstOrDefault(x => x.Key == typeof(T)).Value;
}
else
{
throw new Exception($"The requested view '{typeof(T)}' is not registered");
}
}
public void Register(Type viewType, object viewModel)
{
if (!_storage.ContainsKey(viewType))
{
_storage.Add(viewType, viewModel);
}
else
{
throw new Exception($"An instance of the view model '{viewModel}' is already registered for the view '{viewType}'");
}
}
}
App Setup
public partial class App : Application
{
public static IServiceLocator ServiceLocator { get; private set; }
public static IViewModelLocator ViewModelLocator { get; private set; }
public App()
{
ServiceLocator = new ServiceLocator();
ServiceLocator.Register(typeof(IMyService), new MyService());
ViewModelLocator = new ViewModelLocator();
ViewModelLocator.Register(typeof(MainWindowView), new MainWindowViewModel(ServiceLocator.Get<IMyService>()));
ViewModelLocator.Register(typeof(LoginView), new LoginViewModel());
}
}
Window Code Behind
public partial class MainWindowView : Window
{
public MainWindowView()
{
InitializeComponent();
this.DataContext = App.ViewModelLocator.Get<MainWindowView>();
}
}
Problem
Everything to this point works fine, except that I don't want to have to call the VM locator in code in the code behind. I would like to use it in XAML. I have seen other approaches where they do this:
x:Class="My.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
DataContext="{Binding Source={StaticResource MyViewModelLocator}, Path=Main}">
There are 2 problems here.
- It required a resources entry in App.XAML:
<Application.Resources>
<core:ViewModelLocator x:Key="MyViewModelLocator" />
</Application.Resources> - It requires a property on the VM Locator called "Main". Since these classes are going to be in my framework, there won't be a property for each ViewModel that other apps use on the VM Locator.
What I'd Like
It would be nice if I could do something like:
DataContext="{Binding Path="{x:static TestApp:App.ViewModelLocator.Get<???????>()}"
where the question marks represent the type of the window it's in.
Is there any way to this in XAML?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
modified 5-Apr-22 14:06pm.
|
|
|
|
|
You can't reference generic class in Xaml... However I think you can do something!
How about something like that (pseudo code that might be inspiring)?
DataContext="{Binding Converter={x:Static TestApp:App.ViewModelConverter}, ConvertParameter={x:Type local:MyVMType}}"
Use a Converter with a ConverterParameter?
|
|
|
|
|
Kevin Marois wrote:
public object Get<T>()
{
if (_storage.ContainsKey(typeof(T)))
{
return _storage.FirstOrDefault(x => x.Key == typeof(T)).Value;
}
else
{
throw new Exception($"The requested view '{typeof(T)}' is not registered");
}
} That's a very strange way of using a dictionary. The alternative is simpler and significantly more efficient:
public object Get<T>()
{
if (!_storage.TryGetValue(typeof(T), out var result)) return result;
throw new ArgumentException($"The requested view '{typeof(T)}' is not registered");
}
And the method doesn't have to be generic - you can have a non-generic overload as well:
public object Get(Type viewType)
{
if (viewType is null) throw new ArgumentNullException(nameof(viewType));
if (!_storage.TryGetValue(viewType, out var result)) return result;
throw new ArgumentException($"The requested view '{viewType}' is not registered", nameof(viewType));
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|