WU app XAML binding to Button grid from custom collection - winrt-xaml

I'm quite new to XAML trying to make grid with Toggle buttons
Something like this:
<GridView ItemSource="{Binding ButtonCollection}">
<GridView.ItemTemplate>
<DataTemplate>
<ToggleButton Content="{Binding Label}" IsEnabled="{Binding BEnabled}" IsChecked="{Binding BChecked, Mode=TwoWay}"/>
<DataTemplate>
</GridView.ItemTemplate>
</GridView>
I have
ObservableCollection<ButtonClass> ButtonCollection
also class for buttons
class ButtonClass
{
public string Label {get; set;}
public bool BEnabled {get; set:}
public bool BChecked {get;set;}
}
binding works when page loads buttons are displayed from ObservableCollection
But I want collection to update when button IsChecked value changes
also is there any way to bind function to click method like:
Click="{Binding DoWhenClicked}"
Now it just results in error I think that is because DoWhenClicked isn't in ItemSource.
Summary:
I want to have Grid of toggle buttons that binds to some sort of list/array/collection of data with label, checked status, enabled status.
When toggle button is checked I want it to reflect in my collection.
Also I want to bind event to Click method so that i can perform operations like disable some Toggle Buttons when other button is checked.
What is good way to do this.

I noticed that you asked several question about Template 10 before, so I supposed that you also used Template 10 here for MVVM pattern.
binding works when page loads buttons are displayed from ObservableCollection But I want collection to update when button IsChecked value changes
In Template 10 project, if you want to get notified when parameter in the data model (here means your ButtonClass), you can derive your class from BindableBase. If you check the BindableBase class you will find that it has done the work of INotifyPropertyChanged, it will be much easier here deriving from BindableBase directly rather than implementing INotifyPropertyChanged by yourself.
also is there any way to bind function to click method
Also I want to bind event to Click method so that i can perform operations like disable some Toggle Buttons when other button is checked.
Instead of Click event, I personally recommend you to using Command in MVVM pattern, and you may want to know which Button is clicked, so you can use CommandParameter here. I created a blank template 10 project and here is my sample:
<GridView x:Name="gridView" RelativePanel.Below="pageHeader" Margin="16,12,0,0" ItemsSource="{x:Bind ViewModel.ButtonCollection}">
<GridView.ItemTemplate>
<DataTemplate>
<ToggleButton Width="100" Content="{Binding Label}" IsEnabled="{Binding BEnabled}"
IsChecked="{Binding BChecked, Mode=TwoWay}" Command="{Binding ToggleBtnClickCommand}"
CommandParameter="{Binding Label}" />
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
The ButtonClass is like this:
public class ButtonClass : BindableBase
{
public string Label { get; set; }
public bool BEnabled { get; set; }
private bool _bChecked;
public bool BChecked
{
get { return _bChecked; }
set
{
_bChecked = value;
RaisePropertyChanged();
}
}
public ICommand ToggleBtnClickCommand { get; set; }
}
And the MainPageViewModel:
public class MainPageViewModel : ViewModelBase
{
public ObservableCollection<ButtonClass> ButtonCollection;
public MainPageViewModel()
{
ButtonCollection = new ObservableCollection<ButtonClass>();
for (int i = 0; i < 20; i++)
{
ButtonCollection.Add(new ButtonClass
{
Label = "TButton " + i,
BChecked = true,
BEnabled = true,
ToggleBtnClickCommand = new DelegateCommand<string>(ToggleBtnClicked)
});
}
}
public void ToggleBtnClicked(string obj)
{
var buttonLable = obj;
}
}
In case you need to check my sample, you can find my demo here.

There are a few concepts that are missing from your code that you need to properly implement for this to work
INotifyPropertyChanged -> Your ButtonClass class acts as a view model for your view. As such, for values to properly update UI and the other way around you need your class to implement it and all your properties to raise the PropertyChanged event when their values change (in the setter)
2-Way bindings -> If you want your ButtonClass instance to update when you click the button and you want your button to change state if you change the property in the ButtonClass, your bindings need to be Mode=TwoWay. You might want to explore the new Bindings {x:Bind} for better performance
Commands -> To bind the click event, you need to use the Command property. You would need to create a ICommand implementation, and create a property in your ButtonClass. The use Command property of the Button to bind to that Command.
Essentially, everything I mentioned are components of an MVVM framework, of which there are many out there. Here are some of the more popular ones: Caliburn, MVVMCross, Prism.
There's also a great starter kit for Windows 10 that will definitely kick start your app and contains a lot of this classes already built - Template10

Related

How come PXUIField attribute disables text edit boxes on a processing page in 2019 R1?

I'm trying to setup a processing page that will update a SOShipment document lines with new data entered on the PXFilteredProcessing page. When declaring a PXString (virtual field), if I add the PXUIfield attribute, the field becomes read only.
Here is the DAC declaration showing the actual problem. The page I use is a simple PXFilteredProcessing page with a completely custom page that was made in Visual Studio.
#region StockRow
public abstract class stockRow : IBqlField { }
[PXString()]
[PXUIField(Enabled = true)]
public virtual String StockRow { get; set; }
#endregion
#region StockFlag
public abstract class stockFlag : IBqlField { }
[PXString]
public virtual String StockFlag { get; set; }
#endregion
The page has the fields defined as follow :
<px:PXTextEdit ID="edStockRow" runat="server"
DataField="StockRow" Enabled ="true" >
</px:PXTextEdit>
<px:PXTextEdit ID="edStockFlag" runat="server"
DataField="StockFlag" Enabled ="true">
</px:PXTextEdit>
<px:PXGridColumn DataField="StockRow" Width="200px" >
</px:PXGridColumn>
<px:PXGridColumn DataField="StockFlag" Width="200px">
</px:PXGridColumn>
Should the PXUIField really make the field become read only or is there something I am not getting?
PS: I know I can re-enable the field on the RowSelected even, I'm mostly looking for an explanation as to why this is happening.
if I add the PXUIfield attribute, the field becomes read only
Are you sure that this is the operation making the field read-only?
Typically all processing screen detail fields are disabled except the Selected column. I believe this is a behavior introduced by the use of PXProcessing type data view. Going against that behavior will likely not yield the desired result.
If the screen needs detail fields to be editable (except Selected column) I would advise not to create a processing screen. Using a PXSelect data view instead will provide correct behavior for the editable fields.

How to make a check box editable

Domino 8.5.3 FP5, Designer 9.0.1.
I have an empty xpage containing only the following checkbox. I am not able to make it editable. It show the right value, but appear as disabled.
<xp:checkBox text="Label" id="checkBox1" uncheckedValue="true"
checkedValue="false"
value="#{javascript:jBeanConfigSupport.validationEnabledTxt}">
</xp:checkBox>
If I remove the binding to Java bean, all run fine. This is the Java bean code (part)
private boolean isValidationEnabled=true;
public String getValidationEnabledTxt() {
return String.valueOf(isValidationEnabled);
}
public void setValidationEnabledTxt(String onOff) {
isValidationEnabled=Boolean.parseBoolean(onOff);
}
public void setValidationEnabledTxt(boolean onOff) {
isValidationEnabled=onOff;
}
Where Am I wrong?
You're binding using SSJS, so instead of binding to the validationEnabledTxt property of your bean, the result of jBeanConfigSupport.validationEnabledTxt is being used to determine what it should be bound to. value="#{jBeanConfigSupport.validationEnabledTxt}" should work to map to the getter and setter.
Francesco,
You need to have a working setter method for this to be editable. In your case there is probably a problem with the setValidationEnabledTxt() method that is causing the field in the UI to be readonly.
Try adding "this" to your code so that it reads this.isValidationEnables = Boolean.parseBoolean(onOff);

Doing Drag/Drop without code behind

How can I perform drag and drop operations without adding code to the code-behind file?
Can I do this with Attached Properties?
If so, then how?
At first thought, I would think that I could create an attached property and bind it to whatever drag item's property that's associated to dragging. When the state of that property changes, my attached property's valueChanged method handler would then execute the drag logic that is currently located in my code-behind file.
However, I have not identified such a property for drag status.
NOTE:
I am not using Prism because I am implementing a Windows Phone 8.1 app.
Thus, at this time Prism is not supported.
The following answer relates to the overall pattern of managing events of a UIElement with no code-behind.
Summary:
We can access a control that is using an attached property and within that attached property's metadata object, we can call an event handler when the value of the attached property changes.
The value of the attached property is set to "true" in our XAML file. This will immediately trigger the attached property's metadata object to update state and invoke a method handler for the change in value.
This example demonstrates two controls that will change color during their mouse enter event:
XAML code:
<Window x:Class="Temp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:behaviors="clr-namespace:Temp.Behaviors"
Title="MainWindow" Height="350" Width="525">
<Canvas>
<Ellipse Width="50" Height="50" Fill="Gray" Canvas.Top="0"
behaviors:AttachedProperties.ActivateOnMouseEnter="True" />
<Ellipse Width="50" Height="50" Fill="Gray" Canvas.Left="200"
behaviors:AttachedProperties.ActivateOnMouseEnter="True" />
</Canvas>
</Window>
Attached property code:
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;
namespace Temp.Behaviors
{
public class AttachedProperties : DependencyObject
{
public static readonly DependencyProperty ActivateOnMouseEnterProperty =
DependencyProperty.RegisterAttached("ActivateOnMouseEnter", typeof(bool), typeof(AttachedProperties), new PropertyMetadata(false, ActivateOnMouseEnter_ValueChanged));
private static void ActivateOnMouseEnter_ValueChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
Ellipse element = dependencyObject as Ellipse;
element.MouseEnter += (se, ev) =>
{
element.Fill = new SolidColorBrush(Colors.Orange);
};
}
public static void SetActivateOnMouseEnter(UIElement element, bool value)
{
element.SetValue(ActivateOnMouseEnterProperty, value);
}
}
}
NOTE:
In this code we are repeatedly subscribing to the mouse enter event without ever unsubscribing (which is bad). However, for simplicity, I leave the logic to manage subscriptions out.

XAML - Declare string, with Textbox.Text as value

kinda new to XAML, but I was wondering if it's possible to declare a string variable which contains the value of a Textbox.Text.
<System:String x:Key="AlarmMessage01">
<!-- Textbox text goes here --->
</System:String>
I'm not looking for a solution which depends on code-behind, purely XAML code, and I don't want to enter a static value either.
Can this even be done, and if so could you show me an example?
Kind regards Cvr
<Page.Resources>
<x:String x:Key="myStaticString" >Hello World</x:String>
</Page.Resources>
<TextBlock Text="{StaticResource myStaticString}" />
I have tested it in WinRT or Windows Store projects
If what you need is a value that can be updated dynamically, you can use Dynamic Resources or Data Binding
With Data Binding(this is probably the best approach):
In your ViewModel class:
public string TextBoxValue { get; set; }
public ViewModel(string text)
{
TextBoxValue = text;
}
In your Code-Behind:
public CurrentPage()
{
this.BindingContext = new ViewModel("Text to be displayed");
}
In your XAML file:
<TextBlock Text="{Binding TextBoxValue}" />
And that's that about it.
Meanwhile, if you want to go with Dynamic Resources:
In code-behind file(wherever you want to update the value), you have:
this.Resources["myStringValue"] = "Text to be displayed";
And in XAML, you have:
<TextBlock Text="{DynamicResource myStringValue}" />

Apache Pivot: Swapping pane visibility

I'm having a problem hiding one pane and showing another in my Apache Pivot app. In my BXML file I have two BoxPanes in a window. Pane 1 starts visible and pane 2 starts hidden:
<BoxPane bxml:id="pane1" orientation="vertical" styles="{horizontalAlignment:'center', verticalAlignment:'center'}">
<Label text="Pane 1"/>
<PushButton bxml:id="startButton" buttonData="Start"/>
</BoxPane>
<BoxPane bxml:id="pane2" orientation="vertical" visible="false" styles="{horizontalAlignment:'center', verticalAlignment:'center'}">
<Label text="Pane 2"/>
</BoxPane>
And I have a listener added to the button that should make pane 1 hidden and pane 2 visible:
#BXML private PushButton startButton = null;
#BXML private BoxPane pane1 = null;
#BXML private BoxPane pane2 = null;
#Override
public void initialize(Map<String, Object> namespace, URL location, Resources resources)
{
startButton.getButtonPressListeners().add(new ButtonPressListener()
{
#Override
public void buttonPressed(Button button)
{
start();
}
});
}
private void start()
{
pane1.setVisible(false);
pane2.setVisible(true);
}
When I click the button though, pane 1 is hidden and pane 2 never shows up. Same thing happens when I reverse the order of the statements in start().
Interestingly enough, when I comment out pane1.setVisible(false), then pane 2 does show up when I click the button.
This is my first Pivot app, so maybe there's some fancy container that does what I want to do in a better way, but I'd still like to know what is going on here. What I'm trying to do seems pretty simple, and I'm sort of baffled why it doesn't work.
You might want to try using a CardPane to switch between your two views. The tutorial on that is here: http://pivot.apache.org/tutorials/card-panes.html
The basic idea is to have the CardPane "host" your two BoxPanes, something like this:
<CardPane bxml:id="cardPane">
<BoxPane bxml:id="pane1" ...>
<Label text="Pane 1"/>
...
</BoxPane>
<BoxPane bxml:id="pane2" ...>
<Label text="Pane 2"/>
</BoxPane>
</CardPane>
Make both BoxPanes visible. Then when you want to change between them, use cardPane.setSelectedIndex(...);

Resources