Image for RibbonButton from Resourse.resx in WPF - binding

I'm work in WPF application. For global menu I use Ribbon. I need to add image to RibbonButton (LargeImageSource) from Resource.resx.
I add resource style to xaml file:
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
Then I add my ImageConverter to xaml file:
<conv:ImageConverter x:Key="Conv" />
My C# class ImageConverter:
public class ImageConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is Bitmap)
{
var stream = new MemoryStream();
((Bitmap)value).Save(stream, ImageFormat.Png);
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = stream;
bitmap.EndInit();
return bitmap; // use when you need normal image
var conv = new FormatConvertedBitmap();
conv.BeginInit();
conv.Source = bitmap;
conv.DestinationFormat = PixelFormats.Gray32Float;
conv.EndInit();
return conv; // use when you need grayed image
}
return value;
}
But I don't now huw Binding Image to RibbunButton:
<RibbonButton KeyTip="N"
Label="{x:Static res:Resources.New}"
LargeImageSource="{Binding Source={StaticResource res:Resources},Path=newBtn, Converter={StaticResource Conv}}"/>
But this doesn't work. What I do wrong?

I change XAML code for my RibbonButton:
"{Binding Source={x:Static res:Resources.newBtn}, Converter={StaticResource ImageConverter}}"
And change my ImageConverter:
public class ImageConverter: IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
MemoryStream ms = new MemoryStream();
((System.Drawing.Bitmap)value).Save(ms, System.Drawing.Imaging.ImageFormat.Png);
BitmapImage image = new BitmapImage();
image.BeginInit();
ms.Seek(0, SeekOrigin.Begin);
image.StreamSource = ms;
image.EndInit();
return image;
}
public object ConvertBack(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}

Related

Original data changed after using modified JsonValueProviderFactory to solve maxJsonLength exception

I'm working with some application designed using ASP.NET MVC.
Did spend lot of time trying to solve some problem, but do not have idea what to do to solve it.
As similar code shown below for big JSON will throw exception :
"Error during serialization or deserialization using the JSON JavaScriptSerializer. The length of the string exceeds the value set on the maxJsonLength property.
"
EXAMPLE :
$http.post('/API/PostData',aoData)...
where aoData equals 3K array of JSON, etc.
Added some solution suggested in many questions being asked on stackoverflow.
Did solve that problem just by :
Removing JsonValueProviderFactory from the ValueProviderFactories.Factories
And adding copy of the original class with simple modification such as :
EXAMPLE:
public sealed class LargeJsonValueProviderFactory : ValueProviderFactory
{
private static void AddToBackingStore(LargeJsonValueProviderFactory.EntryLimitedDictionary backingStore, string prefix, object value)
{
IDictionary<string, object> dictionary = value as IDictionary<string, object>;
if (dictionary != null)
{
foreach (KeyValuePair<string, object> keyValuePair in (IEnumerable<KeyValuePair<string, object>>) dictionary)
LargeJsonValueProviderFactory.AddToBackingStore(backingStore, LargeJsonValueProviderFactory.MakePropertyKey(prefix, keyValuePair.Key), keyValuePair.Value);
}
else
{
IList list = value as IList;
if (list != null)
{
for (int index = 0; index < list.Count; ++index)
LargeJsonValueProviderFactory.AddToBackingStore(backingStore, LargeJsonValueProviderFactory.MakeArrayKey(prefix, index), list[index]);
}
else
backingStore.Add(prefix, value);
}
}
private static object GetDeserializedObject(ControllerContext controllerContext)
{
if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
return (object) null;
string end = new StreamReader(controllerContext.HttpContext.Request.InputStream).ReadToEnd();
if (string.IsNullOrEmpty(end))
return (object) null;
var serializer = new JavaScriptSerializer {MaxJsonLength = Int32.MaxValue};
return serializer.DeserializeObject(end);
}
/// <summary>Returns a JSON value-provider object for the specified controller context.</summary>
/// <returns>A JSON value-provider object for the specified controller context.</returns>
/// <param name="controllerContext">The controller context.</param>
public override IValueProvider GetValueProvider(ControllerContext controllerContext)
{
if (controllerContext == null)
throw new ArgumentNullException("controllerContext");
object deserializedObject = LargeJsonValueProviderFactory.GetDeserializedObject(controllerContext);
if (deserializedObject == null)
return (IValueProvider) null;
Dictionary<string, object> dictionary = new Dictionary<string, object>((IEqualityComparer<string>) StringComparer.OrdinalIgnoreCase);
LargeJsonValueProviderFactory.AddToBackingStore(new LargeJsonValueProviderFactory.EntryLimitedDictionary((IDictionary<string, object>) dictionary), string.Empty, deserializedObject);
return (IValueProvider) new DictionaryValueProvider<object>((IDictionary<string, object>) dictionary, CultureInfo.CurrentCulture);
}
private static string MakeArrayKey(string prefix, int index)
{
return prefix + "[" + index.ToString((IFormatProvider) CultureInfo.InvariantCulture) + "]";
}
private static string MakePropertyKey(string prefix, string propertyName)
{
if (!string.IsNullOrEmpty(prefix))
return prefix + "." + propertyName;
return propertyName;
}
private class EntryLimitedDictionary
{
private static int _maximumDepth = LargeJsonValueProviderFactory.EntryLimitedDictionary.GetMaximumDepth();
private readonly IDictionary<string, object> _innerDictionary;
private int _itemCount;
public EntryLimitedDictionary(IDictionary<string, object> innerDictionary)
{
this._innerDictionary = innerDictionary;
}
public void Add(string key, object value)
{
if (++this._itemCount > LargeJsonValueProviderFactory.EntryLimitedDictionary._maximumDepth)
throw new InvalidOperationException("JsonValueProviderFactory_RequestTooLarge");
this._innerDictionary.Add(key, value);
}
private static int GetMaximumDepth()
{
NameValueCollection appSettings = ConfigurationManager.AppSettings;
if (appSettings != null)
{
string[] values = appSettings.GetValues("aspnet:MaxJsonDeserializerMembers");
int result;
if (values != null && values.Length > 0 && int.TryParse(values[0], out result))
return result;
}
return 1000;
}
}
}
And that solve the problem with maxJsonLength. Great! But...
If JSON contains property called ACTION, controller get data being changed. The ACTION property contains name of the controller's action instead of "MAR". The LargeJsonValueProviderFactory class does not change value of the ACION property. But if LargeJsonValueProviderFactory class shown above is not is use issue disappears.
EXAMPLE :
{
NR : 1200,
ACTION : "MAR",
.....
}
public ActionResult Save(PrsentationEntity aoData)
{
aoData.NR equals 1200 - OK
aoData.ACTION equals "Save" -Should be "MAR"
Do you have any ideas why I have that problem ?
Regards
Marcin
tl;dr
When configuring the application the original JsonValueProviderFactory should be replaced by the custom LargeJsonValueProviderFactory instead of added to the end of the collection.
Long version
You said you solved the problem by:
Removing JsonValueProviderFactory from the ValueProviderFactories.Factories
And adding copy of the original class with simple modification such as :
That's why the problem occurs.
The order of the factories on ValueProviderFactories.Factories does matter, but it's not generally discussed.
The original order is this:
private static readonly ValueProviderFactoryCollection _factories = new ValueProviderFactoryCollection()
{
new ChildActionValueProviderFactory(),
new FormValueProviderFactory(),
new JsonValueProviderFactory(),
new RouteDataValueProviderFactory(),
new QueryStringValueProviderFactory(),
new HttpFileCollectionValueProviderFactory(),
new JQueryFormValueProviderFactory()
};
If you just add your new provider to the end of the collection it won't be used if one of the other providers does the job (in this case it seems that RouteDataValueProviderFactory was used).

Mvvmcross WithFormat() not firing

I'm trying to formatting a byte[] to a string for displaying in IOs application, here what
The problem is that the Converter never fires up
I actually have:
Converter class
class ByteArrayToTextValueConverter : MvxValueConverter<byte[], string>
{
protected override string Convert(byte[] value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is byte[])
{
return "test";
/*
var byteArray = (byte[])value;
return Encoding.UTF8.GetString(byteArray, 0, byteArray.Length);
*/
}
return "";
}
protected override byte[] ConvertBack(string value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is string)
{
var text = (string)value;
return Encoding.UTF8.GetBytes(text);
}
return new byte[] { };
}
}
View scrap:
var source = new MvxSimpleTableViewSource(
TableView,
SubtitleDetailViewCell.Key,
SubtitleDetailViewCell.Key
);
TableView.Source = source;
TableView.RowHeight = 50;
TableView.RegisterClassForCellReuse(typeof(SubtitleDetailViewCell), SubtitleDetailViewCell.Key);
var set = this.CreateBindingSet<ObservationsView, ObservationsViewModel>();
set.Bind(source).To(vm => vm.Observations);
//set.Bind(source).For(s => s.SelectionChangedCommand).To(vm => vm.SelectedObsCommand);
set.Apply();
TableView.ReloadData();
Custom cell class:
public SubtitleDetailViewCell(IntPtr handle)
: base(handle)
{
Initialize();
this.DelayBind(() =>
{
var set = this.CreateBindingSet<SubtitleDetailViewCell, ObservationMedicale>();
set.Bind(MainLbl).To(observation => observation.Texte).WithConversion("ByteArrayToText");
set.Bind(SubLeftLbl).To(observation => observation.SaisieLe);
set.Bind(SubRightLbl).To(observation => observation.PraticienNom);
set.Apply();
});
}
This might be as simple as the fact that your ByteArrayToTextValueConverter is internal rather than public - so MvvmCross doesn't have permission to access it.
If you do want to keep it internal, then you can also use the alternative format of WithConversion:
.WithConversion(new ByteArrayToTextValueConverter(), null);
Beyond that, I'm also unsure why you would apply the ByteArrayToText conversion on the list of Observations - it looks more like the source should be a collection of ObservationMedicale objects

Howto get multiple data from a custom component to the backend bean?

I have a data object called DeliveryPeriod which is a container for a start and a end date (saved as String like dd.MM.yyy, comes from the database) an the id of another object called PlanningPeriod. This delivery period should be displayed in its own custom component in JSF like
<myc:deliveryPeriodComponent value="#{backendBean.deliveryPeriod}" />
I implement a class DeliveryPeriodComponent which extends UIInput and a DeliveryPeriodComponentRenderer which extendes javax.faces.renderer. The rendering works well, i see two calender elements and a SelectOneMenu to choose the planning period. But render the data is not all, I need to change the data as well. And here comes the problem, i have no idea to get the data inside my component to the backend bean. The decode() method did not know the new values and the other methods are never called. I didn't know the trick, how to connect the JSF page to the bean, from the tutorial (http://jsfatwork.irian.at, i bought the book) i had these methods like getValue() and getConverter().
Here is the code from the component:
public class DeliveryPeriodComponent extends UIInput {
public static final String COMPONENT_TYPE = "de.hacon.tps.integrator.web.component.deliveryperiod.DeliveryPeriodComponent";
enum PropertyKeys {
begin, end, planningPeriod
}
public DeliveryPeriodComponent() {
setRendererType("de.hacon.tps.integrator.web.component.deliveryperiod.DeliveryPeriodComponent");
}
public String getBegin() {
return (String) getStateHelper().eval(PropertyKeys.begin, "01.01.2012");
}
public void setBegin(String begin) {
getStateHelper().put(PropertyKeys.begin, begin);
}
public String getEnd() {
return (String) getStateHelper().eval(PropertyKeys.end, "31.12.2012");
}
public void setEnd(String end) {
getStateHelper().put(PropertyKeys.end, end);
}
public int getPlanningPeriod() {
return (Integer) getStateHelper().eval(PropertyKeys.planningPeriod, 0);
}
public void setPlanningPeriod(int planningPeriod) {
getStateHelper().put(PropertyKeys.planningPeriod, planningPeriod);
}}
And here is the renderer:
public class DeliveryPeriodComponentRenderer extends Renderer {
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy");
#Override
public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
DeliveryPeriodComponent comp = (DeliveryPeriodComponent) component;
String clientId = comp.getId();
try {
encodeInput(context, comp, clientId);
} catch (ParseException e) {
e.printStackTrace();
}
}
private void encodeInput(FacesContext context, DeliveryPeriodComponent comp, String clientId) throws ParseException {
comp.getChildren().clear();
DeliveryPeriod value = (DeliveryPeriod) comp.getAttributes().get("value");
List<PlanningPeriodSubset> pp = (List<PlanningPeriodSubset>) comp.getAttributes().get("periods");
HtmlPanelGrid pGrid = new HtmlPanelGrid();
pGrid.setColumns(4);
Calendar cBegin = new Calendar();
cBegin.setShowOn("button");
cBegin.setValue(sdf.parse(value.getStartDate()));
cBegin.setPattern("dd.MM.yyyy");
pGrid.getChildren().add(cBegin);
Calendar cEnd = new Calendar();
cEnd.setShowOn("button");
cEnd.setValue(sdf.parse(value.getEndDate()));
cEnd.setPattern("dd.MM.yyyy");
pGrid.getChildren().add(cEnd);
HtmlSelectOneMenu sPlanningPeriod = new HtmlSelectOneMenu();
Collection<UISelectItem> items = new ArrayList<UISelectItem>();
for (PlanningPeriodSubset op : pp) {
UISelectItem item = new UISelectItem();
item.setItemLabel(op.getName());
item.setItemValue(op.getId());
items.add(item);
}
sPlanningPeriod.getChildren().addAll(items);
sPlanningPeriod.setValue(value.getPlanningPeriodId());
pGrid.getChildren().add(sPlanningPeriod);
HtmlPanelGrid buttonPanel = new HtmlPanelGrid();
buttonPanel.setColumns(2);
Button bDelete = new Button();
bDelete.setValue(" - ");
buttonPanel.getChildren().add(bDelete);
Button bInfo = new Button();
bInfo.setValue(" i ");
buttonPanel.getChildren().add(bInfo);
pGrid.getChildren().add(buttonPanel);
comp.getChildren().add(pGrid);
}
#Override
public void decode(FacesContext context, UIComponent component) {
DeliveryPeriodComponent deliveryComponent = (DeliveryPeriodComponent) component;
DeliveryPeriod deliveryPeriod = new DeliveryPeriod();
deliveryPeriod.setStartDate(deliveryComponent.getBegin());
deliveryPeriod.setEndDate(deliveryComponent.getEnd());
deliveryPeriod.setPlanningPeriodId(deliveryComponent.getPlanningPeriod());
// Map<String, String> params = context.getExternalContext().getRequestParameterMap();
// String clientId = component.getClientId();
// String value = params.get(clientId);
// ((UIInput) component).setSubmittedValue(value);
}
#Override
public Object getConvertedValue(FacesContext context, UIComponent component, Object submittedValue)
throws ConverterException {
Converter converter = getConverter(context, (DeliveryPeriodComponent) component);
if (converter != null) {
return converter.getAsObject(context, component, (String) submittedValue);
} else {
return submittedValue;
}
}
private Object getValue(FacesContext context, DeliveryPeriodComponent comp) {
Object submittedValue = comp.getSubmittedValue();
if (submittedValue != null) {
return submittedValue;
}
Object begin = comp.getBegin();
Object end = comp.getEnd();
Object planningPeriod = comp.getPlanningPeriod();
DeliveryPeriod period = new DeliveryPeriod();
period.setStartDate((String) begin);
period.setEndDate((String) end);
period.setPlanningPeriodId((Integer) planningPeriod);
Converter converter = this.getConverter(context, comp);
if (converter != null) {
return converter.getAsString(context, comp, period);
} else if (period != null) {
return period.toString();
} else {
return "";
}
}
private Converter getConverter(FacesContext context, DeliveryPeriodComponent comp) {
Converter conv = ((UIInput) comp).getConverter();
if (conv != null) {
ValueExpression exp = comp.getValueExpression("value");
if (exp == null) {
return null;
} else {
Class valueType = exp.getType(context.getELContext());
if (valueType == null) {
return null;
} else {
return context.getApplication().createConverter(valueType);
}
}
}
return null;
}}
Maybe this is a trivial problem, I am not a pro at JSF and still learning. And it is very hard to write your own components when you almost confused about the basics :-( Still learning new things every day. Thank you for your help!
(I found a lot on custom components with examples like a custum inputfields, these components works well and transfer their data. Unfortunatly I found nothing on custom components which contains more then one input field or did something different from the existing JSF elements)
In Xhtml Page Call your listner with
<h:commandButton id="add" value="Add More" styleClass="input_right_cor" type="button">
<f:ajax execute="#this" listener="#{templateSearchHandler.AddRow}" />
</h:commandButton>

how to bind the DataGridTextColumn visibility

I am trying to bind the visibility of datagrid as GreatTall1 suggested in his post from this thread
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace XYZ.Controls
{
public class ExtendedDataGridTextColumn : DataGridTextColumn
{
private readonly Notifier _e;
private Binding _visibilityBinding;
public Binding VisibilityBinding
{
get { return _visibilityBinding; }
set
{
_visibilityBinding = value;
_e.SetBinding(Notifier.MyVisibilityProperty, _visibilityBinding);
}
}
public ExtendedDataGridTextColumn()
{
_e = new Notifier();
_e.PropertyChanged += ToggleVisibility;
}
private void ToggleVisibility(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "Visibility")
this.Visibility = _e.MyVisibility;
}
//Notifier class is just used to pass the property changed event back to the column container Dependency Object, leaving it as a private inner class for now
private class Notifier : FrameworkElement, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public Visibility MyVisibility
{
get { return (Visibility)GetValue(MyVisibilityProperty); }
private set { SetValue(MyVisibilityProperty, value); }
}
public static readonly DependencyProperty MyVisibilityProperty = DependencyProperty.Register("MyVisibility", typeof(Visibility), typeof(Notifier), new PropertyMetadata(MyVisibilityChanged));
private static void MyVisibilityChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var n = d as Notifier;
if (n != null)
{
// n.MyVisibility = (Visibility) e.NewValue;
n.PropertyChanged(n, new PropertyChangedEventArgs("Visibility"));
}
}
}
}
I have added the class to my solution, and try to bind the DataGridTextColumn visibility to my IdVisibility property
<sdk:DataGrid x:Name="dgResult" Grid.Row="0" VerticalAlignment="Stretch" SelectionMode="Single" HorizontalAlignment="Stretch" AutoGenerateColumns="False" ItemsSource="{Binding IdSearchList}" IsReadOnly="True" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Margin="10" Visibility="{Binding IsResultVisible}">
<extDg:ExtendedDataGridTextColumn Binding="{Binding Id}" VisibilityBinding="{Binding IdVisibility}" Header="Asset ID" Width="50"/>
private Visibility idVisibility = Visibility.Collapsed;
public Visibility IdVisibility
{
get { return idVisibility; }
set { idVisibility = value; NotifyPropertyChanged("IdVisibility"); }
}
The column is always being displayed regardless of the value of IdVisibility.
Please, could someone point out what i am doing wrong? This is a SL4 app
Thanks
I Think You Should Use Visiblity Converter Also You Can Bind With Designer with This Converter
Public NotInheritable Class VisibilityConverter
Implements IValueConverter
Public Function Convert(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.Convert
If Not targetType Is GetType(Visibility) Then
Throw New ArgumentOutOfRangeException("targetType", "VisibilityConverter can only convert to Visibility")
End If
Dim _visibility As Visibility = Visibility.Visible
If value Is Nothing Then
_visibility = Visibility.Collapsed
End If
If TypeOf (value) Is Boolean Then
_visibility = IIf(value, Visibility.Visible, Visibility.Collapsed)
End If
If TypeOf (value) Is String Then
_visibility = IIf(String.IsNullOrEmpty(value), Visibility.Collapsed, Visibility.Visible)
End If
Return _visibility
End Function
Public Function ConvertBack(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.ConvertBack
Throw New ArgumentOutOfRangeException("targetType", "VisibilityConverter can only convert to Boolean")
End Function
End Class

ActionListener is not being called on dynamically created HtmlCommandLink

I have a dynamically created HtmlCommandLink with an ActionListener, but when I click on the link, the action listener method is not being called.
Code:
public HtmlPanelGroup getP() {
p = new HtmlPanelGroup();
FacesContext ctx = FacesContext.getCurrentInstance();
HtmlCommandLink l = new HtmlCommandLink();
l.setTitle("Goto");
l.setImmediate(true);
l.addActionListener(new ComponenetListener());
//new ListenerTest());//new MethodExpressionActionListener(methodExpression) );
l.setValue("Go");
p.getChildren().add(l);
return p;
}
and listener code is
#ManagedBean
#SessionScoped
public class ComponenetListener implements ActionListener{
public ComponenetListener() {
String s="sridhar";
}
#Override
public void processAction(ActionEvent event) throws AbortProcessingException {
UIComponent eventComponent = event.getComponent();
System.out.println("test");
String strEventCompID = eventComponent.getId();
throw new UnsupportedOperationException("Not supported yet.");
}
}
You must give all your dynamically created input and command components a fixed ID.
l.setId("yourID");
You also need to ensure that there's a <h:form> (or UIForm) component present as tree parent.

Resources