I am extremely new to silverlight working on a new control called pivotviewer in silverlight 5.
I am trying to write a doubleclick event for the pivot viewer from an existing silverlight 4 code.
//double click event
private void PivotViewerControl_ItemDoubleClicked(object sender, ItemEventArgs e)
{
PivotItem piv_item =PivotViewerControl1.GetItem(e.ItemId);
if (!string.IsNullOrWhiteSpace(piv_item.Href))
{
PivotViewerControl1.CurrentItemId = e.ItemId;
OpenLink(piv_item.Href);
}
else
{
MessageBox.Show("No Web Page...");
}
}
while translating this to silverlight 5 where pivotviewer is inbuilt control the following stub is created for the event.
private void PivotViewerControl_ItemDoubleClicked(object sender, PivotViewerItemDoubleClickEventArgs e)
{
//here the pivotviewercontrol has not getitem() in silverlight 5 so How do i get the currently selected
//Item on the double click
}
Also I am not getting the images on the page load itself. My page load code is as follows
public MainPage()
{
InitializeComponent();
PivotViewerControl.Loaded += PivotViewerControl_Loaded;
}
void PivotViewerControl_Loaded(object sender, RoutedEventArgs e)
{
_cxml = new CxmlCollectionSource(new Uri(MauritiusCollectionUri, UriKind.RelativeOrAbsolute));
_cxml.StateChanged += _cxml_StateChanged;
}
void _cxml_StateChanged(object sender, CxmlCollectionStateChangedEventArgs e)
{
if (e.NewState == CxmlCollectionState.Loaded)
{
PivotViewerControl.PivotProperties = _cxml.ItemProperties.ToList();
PivotViewerControl.ItemTemplates =_cxml.ItemTemplates;
PivotViewerControl.ItemsSource =_cxml.Items;
}
}
On running I am only getting the images when I sort or do some search can anyone tell me why? Thanks
Hi the double click event I have able to translate is as follows
private void PivotViewerControl_ItemDoubleClicked(object sender,
PivotViewerItemDoubleClickEventArgs e)
{
PivotViewerItem piv_item = (PivotViewerItem)e.Item;
if(piv_item.Properties[0]!=null && piv_item.Properties[0].ToString()!=string.Empty)
{
OpenLink(piv_item.GetPropertyValue("Href")[0].ToString());
}
}
Related
I've got the following setup: A MainPage xaml-view and a SettingPage xaml-view. In the SettingPage xaml-view I activated the back button which is in the window title bar and I added a BackRequestedEventArgs. (Furthermore I have a DX12 xaml page but it is not involved to the navigation yet, so it will never get initialized.)
So my problem is: if I click on a flyoutitem called settings which is located in the MainPage, I'll get navigated to the SettingPage. The backbutton appears in the titlebar and if I click it, I get back to the MainPage. Now I do it once again: clicking on settings, navigating to SettingPage. Now if I click on the backbutton OR close the window the app crashes and shows me the following exception:
Platform::DisconnectedException ^ at 0x046BED80. HRESULT:0x80010108
My Question: How do I fix it?
Here is my Code for it:
MainPage Navigation:
void MainPage::MenuFlyoutItemSettings_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
this->Frame->Navigate(Windows::UI::Xaml::Interop::TypeName(SettingsPage::typeid));
}
SettingsPage:
// in Constructor
Windows::UI::Core::SystemNavigationManager::GetForCurrentView()->AppViewBackButtonVisibility = Windows::UI::Core::AppViewBackButtonVisibility::Visible;
Windows::UI::Core::SystemNavigationManager::GetForCurrentView()->
BackRequested += ref new Windows::Foundation::EventHandler<
Windows::UI::Core::BackRequestedEventArgs^>(
this, &SettingsPage::App_BackRequested);
void SettingsPage::App_BackRequested(
Platform::Object^ sender,
Windows::UI::Core::BackRequestedEventArgs^ e)
{
Windows::UI::Xaml::Controls::Frame^ rootFrame = dynamic_cast<Windows::UI::Xaml::Controls::Frame^>(Window::Current->Content);
if (rootFrame == nullptr)
return;
// Navigate back if possible, and if the event has not
// already been handled.
if (rootFrame->CanGoBack && e->Handled == false)
{
e->Handled = true;
rootFrame->GoBack();
}
}
Furthermore both methods have onSuspending and onResuming handlers added by me manually, but they are both empty:
//in constructor
Application::Current->Suspending += ref new SuspendingEventHandler(this, &SettingsPage::OnSuspending);
Application::Current->Resuming += ref new EventHandler<Object^>(this, &SettingsPage::OnResuming);
void SettingsPage::OnSuspending(Object^ sender, SuspendingEventArgs^ e) {
}
void SettingsPage::OnResuming(Object^ sender, Object^ e) {
}
NOTE: If I delete the whole backbutton-code, the app never crashes with this exception, so I think it is an error in this code.
EDIT 2017-09-04:
After working on Sunteen Wu - MSFT's Answer from below I realised that even If I delete all the backbutton-code I will get this exception as soon as I enter the SettingsPage the first time and close the app. So here is my current scenario where I am getting the described exception:
The only code I've got now for navigation:
MainPage (in a custom settingsbutton):
this->Frame->Navigate(Windows::UI::Xaml::Interop::TypeName(SettingsPage::typeid));
SettingsPage (in a custom backbutton):
this->Frame->Navigate(Windows::UI::Xaml::Interop::TypeName(MainPage::typeid));
So after the first time I navigate to the settingspage by pressing the settingsbutton I get the described exception only if I shutdown the app (same if clicking on red x or stopping debugger). The navigation works fine though, I can swap between the pages as long as I want and I won't get the exception while running the app.
FINAL ANSWER 2017-09-06:
Combining Sunteen Wu - MSFT's Answer with deleting the above mentioned
Application::Current->Suspending += ref new SuspendingEventHandler(this, &SettingsPage::OnSuspending);
Application::Current->Resuming += ref new EventHandler<Object^>(this, &SettingsPage::OnResuming);
handlers is the solution for me. Now there is no Disconnectedexception and the Back-Button-Logic is also working!
Platform::DisconnectedException ^ at 0x046BED80. HRESULT:0x80010108
Actually you are meeting the cycles issue. For what it the cycles issue and how to resolve please reference Weak references and breaking cycles (C++/CX). You met the cycles issue when you subscribe the BackRequested event handle. With the WeakReference you will find the issue:
WeakReference wr(this);
Windows::UI::Core::SystemNavigationManager::GetForCurrentView()->
BackRequested += ref new Windows::Foundation::EventHandler<
Windows::UI::Core::BackRequestedEventArgs^>([wr](
Object^ sender, Windows::UI::Core::BackRequestedEventArgs^ e)
{
SettingsPage^ c = wr.Resolve<SettingsPage>();
if (c != nullptr)
{
Windows::UI::Xaml::Controls::Frame^ rootFrame = dynamic_cast<Windows::UI::Xaml::Controls::Frame^>(Window::Current->Content);
if (rootFrame == nullptr)
return;
if (rootFrame->CanGoBack && e->Handled == false)
{
e->Handled = true;
rootFrame->GoBack();
}
}
else
{
throw ref new DisconnectedException();
}
});
From the article, when an event handler throws DisconnectedException, it causes the event to remove the handler from the subscriber list. So that to resolve it, you can remove the event handle from subscriber list after back requested. The following code snippet showed how to remove.
Windows::Foundation::EventRegistrationToken cookie;
SettingsPage::SettingsPage()
{
InitializeComponent();
...
cookie = Windows::UI::Core::SystemNavigationManager::GetForCurrentView()->
BackRequested += ref new Windows::Foundation::EventHandler<
Windows::UI::Core::BackRequestedEventArgs^>(
this, &SettingsPage::App_BackRequested);
}
void SettingsPage::App_BackRequested(
Platform::Object^ sender,
Windows::UI::Core::BackRequestedEventArgs^ e)
{
...
Windows::UI::Core::SystemNavigationManager::GetForCurrentView()->
BackRequested -= cookie;
}
Additionally, I recommend you subscribe this event inside App.xaml.cpp to avoid this issue. You can subscribe it inside OnLaunched like follows:
void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e)
{
auto rootFrame = dynamic_cast<Frame^>(Window::Current->Content);
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == nullptr)
{
...
}
else
{
...
}
Windows::UI::Core::SystemNavigationManager::GetForCurrentView()->
BackRequested += ref new Windows::Foundation::EventHandler<
Windows::UI::Core::BackRequestedEventArgs^>(
this, &App::App_BackRequested);
}
void App::App_BackRequested(
Platform::Object^ sender,
Windows::UI::Core::BackRequestedEventArgs^ e)
{
...
}
More details you can reference BackButton official sample.
I have basically implemented the new XE12\GDK2 cameramanager sample code to capture an image on application start. However, the notification to the FileObserver callback takes anywhere from 3 to 30 seconds to get the notification of the image file creation. Taking a picture using the default 'Take a Picture' app works just fine so I dont thin it is an OS\update issue.
My app's behavior is like:
- Take the picture
- Tap to accept
Wait 3 to 30 seconds
- Get the callback and the imageview is updated with the captured image.
I dont think I have modified a single line of the sample code provided in the GDK 2.0 camera tutorial. So wondering what I am missing.
I have attached the relevant section of the code below. Any tips\pointers highly appreciated.
#Override
protected void onStart() {
super.onStart();
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// String path = Environment.getExternalStorageDirectory().getPath();
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
private void processPictureWhenReady(final String picturePath) {
final File pictureFile = new File(picturePath);
if (pictureFile.exists()) {
// The picture is ready; process it. Takes 3-30 seconds to get here!
try {
Bitmap imageBitmap = BitmapFactory.decodeFile(picturePath);
int w = imageBitmap.getWidth();
int h = imageBitmap.getHeight();
Bitmap bm2 = Bitmap.createScaledBitmap(imageBitmap, w/2, h/2, true);
imageBitmap = bm2.copy(bm2.getConfig(), true);
//m_ImageView.setImageBitmap(bm2);
} catch (Exception e) {
Log.e("Exc", e.getMessage());
}
} else {
tm = System.currentTimeMillis();
// The file does not exist yet. Before starting the file observer, you
// can update your UI to let the user know that the application is
// waiting for the picture (for example, by displaying the thumbnail
// image and a progress indicator).
final File parentDirectory = pictureFile.getParentFile();
FileObserver observer = new FileObserver(parentDirectory.getPath()) {
// Protect against additional pending events after CLOSE_WRITE is
// handled.
private boolean isFileWritten;
#Override
public void onEvent(int event, String path) {
if (!isFileWritten) {
// For safety, make sure that the file that was created in
// the directory is actually the one that we're expecting.
File affectedFile = new File(parentDirectory, path);
isFileWritten = (event == FileObserver.CLOSE_WRITE
&& affectedFile.equals(pictureFile));
if (isFileWritten) {
stopWatching();
// Now that the file is ready, recursively call
// processPictureWhenReady again (on the UI thread).
runOnUiThread(new Runnable() {
#Override
public void run() {
processPictureWhenReady(picturePath);
}
});
}
}
}
};
observer.startWatching();
}
}
Answering my own question - though I got the clarifications from Jenny Murphy and John Feig :-). Hopefully it helps others.
To the first point - why is image capture using the sample code from the GDK guide so slow:
This is the expected behavior. The Glass camera intent (ACTION_IMAGE_CAPTURE) performs a ton of proprietary post-processing on the captured image - auto-HDR etc which takes time. This is cleverly disguised in the 'Take a picture' command by only displaying the preview image (which is available immediately.). As proof, try to find the image you just took in your time-line. You will not see it for several seconds (around 8 seconds on average in my experience.).
Frankly, unless you are ok just grabbing the preview image, the camera intent may not be very useful in most apps.
The solution is to use the Camera directly using default Android APIs. For convenience, I have pasted a snippet of this code. Please excuse if it is kind of basic for many of you. A lot of the code is copied from John Feig's GIFCamera glassware on GitHub
activity_main layout contains a SurfaceView called preview
<SurfaceView
android:id="#+id/preview"
android:layout_width="500dp"
android:layout_height="500dp"
android:layout_alignParentTop="true"
android:layout_marginTop="20dp"
/>
MainActivity.java
public class MainActivity extends Activity implements PhotoCallback {
public byte[] m_jpg = null;
Camera cam = null;
SurfaceHolder m_sh;
private final SurfaceHolder.Callback mSurfaceHolderCallback = new SurfaceHolder.Callback() {
#Override
public void surfaceCreated(SurfaceHolder hldr) {
m_sh = hldr;
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
myCapHandler2(); //Start Camera Preview etc.
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SurfaceView preview = (SurfaceView) findViewById(R.id.preview);
preview.getHolder().addCallback(mSurfaceHolderCallback);
}
public void myCapHandler2() {
//open camera
try {
cam = Camera.open(0);
Camera.Parameters params = cam.getParameters();
List<Size> sizes = params.getSupportedPreviewSizes();
params.setJpegQuality(90);
params.setPreviewFpsRange(30000, 30000);
params.setPictureSize(sizes.get(1).width, sizes.get(1).height);
params.setPreviewSize(sizes.get(1).width, sizes.get(1).height);
cam.setParameters(params);
try {
cam.setPreviewDisplay(m_sh);
}
catch (IOException e) {
e.printStackTrace();
}
// Important: Call startPreview() to start updating the preview
// surface. Preview must be started before you can take a picture.
cam.startPreview();
cam.takePicture(null, null,
new PhotoHandler(this));
} catch (Exception e) {
if (null != cam) {
cam.stopPreview();
cam.release();
}
}
}
#Override
public void pictureTaken(byte[] jpg) {
m_jpg = jpg;
//Picture captured - release the camera for other apps
cam.stopPreview();
cam.release();
}
#Override
public void onPause() {
if (null != cam) {
cam.stopPreview();
cam.release();
}
}
#Override
public void onDestroy() {
if (null != cam) {
cam.stopPreview();
cam.release();
}
}
}
PhotoHandler.java
import android.hardware.Camera;
import android.os.AsyncTask;
public class PhotoHandler implements Camera.PictureCallback {
private PhotoCallback photoCallback;
public PhotoHandler(PhotoCallback photoCallback) {
super();
this.photoCallback = photoCallback;
}
#Override
public void onPictureTaken(byte[] data, Camera camera) {
new ProcessCapturedImage().execute(data);
}
private class ProcessCapturedImage extends AsyncTask<byte[], Void, byte[]> {
#Override
protected byte[] doInBackground(byte[]... params) {
if (null == params || null == params[0])
return null;
return params[0];
}
#Override
protected void onPostExecute(byte[] params) {
photoCallback.pictureTaken(params);
}
}
}
PhotoCallback.java
public interface PhotoCallback {
public void pictureTaken(byte[] jpg);
}
All the best with your camera glassware.
After entering a value in the AddNewRecord row, and clicking anywhere outside the row on the XamDataGrid seems to add the row to the collection.
How do I prevent mouse click from adding a new row to the collection.
Kindly any help
Clicking outside of the AddNewRecord ends edit mode on the record and if there were changes they are committed at that time which means the new record is added. If you were looking to only allow the record to be commmited when pressing the enter key and not by clicking another record in the grid, then you could use the following logic to set the mouse left button down as handled:
private bool editingAddNewRecord = false;
void XamDataGrid1_EditModeEnded(object sender, Infragistics.Windows.DataPresenter.Events.EditModeEndedEventArgs e)
{
this.editingAddNewRecord = false;
}
void XamDataGrid1_EditModeStarted(object sender, Infragistics.Windows.DataPresenter.Events.EditModeStartedEventArgs e)
{
this.editingAddNewRecord = e.Cell.Record.IsAddRecord;
}
void XamDataGrid1_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (editingAddNewRecord)
{
DataRecordPresenter drp = Infragistics.Windows.Utilities.GetAncestorFromType(e.OriginalSource as DependencyObject, typeof(DataRecordPresenter), true) as DataRecordPresenter;
if (!(drp != null && drp.IsAddRecord))
{
e.Handled = true;
}
}
}
Thanks for the answer #alhalama!
I noticed though that you don't handle the right mouse button down, and even when we do your solution doesn't work to support it. Also, with your solution I wasn't able to edit any other cells until I had hit Enter or Escape on the Add New Row record (which might be what some people want, but not me). Here is my modified solution that undoes changes to the Add New Record row's cell when the user clicks out of it, which also handles all mouse clicks (left, right, middle, etc.).
// Used to record when the user is editing a value in the Mass Edit row.
private DataRecord _addRecordCellBeingEdited = null;
private void XamDataGrid1_EditModeStarted(object sender, Infragistics.Windows.DataPresenter.Events.EditModeStartedEventArgs e)
{
if (e.Cell.Record.IsAddRecord)
_addRecordCellBeingEdited = e.Cell.Record;
}
private void XamDataGrid1_EditModeEnded(object sender, Infragistics.Windows.DataPresenter.Events.EditModeEndedEventArgs e)
{
_addRecordCellBeingEdited = null;
}
private void XamDataGrid1_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
if (_addRecordCellBeingEdited != null)
{
DataRecordPresenter drp = Infragistics.Windows.Utilities.GetAncestorFromType(e.OriginalSource as DependencyObject, typeof(DataRecordPresenter), true) as DataRecordPresenter;
if (!(drp != null && drp.IsAddRecord))
{
_addRecordCellBeingEdited.CancelUpdate();
}
}
}
I'm a newbie using Infragistics. I'm trying to add context menu to a specific row/column in UltraWinGrid, which I'm not able to. Looks like adding context menu to the grid is simple but adding it to a specific row/column is not straight forward. Can you please tell me how to do this?
You could add a context menu to the form or control your grid will reside in and only display it in when they right click in the grid over the rows/cells that need that menu.
Here's an example, though it's not pretty.
private void UltraGrid_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
ContextMenu.Hide();
Point point = new System.Drawing.Point(e.X, e.Y);
UIElement uiElement = ((UltraGridBase) sender).DisplayLayout.UIElement.ElementFromPoint(point);
UltraGridCell cell = (UltraGridCell) uiElement.GetContext(typeof (UltraGridCell));
if (cell != null && UseThisContextMenu(cell))
{
ContextMenu.Show();
}
}
}
MouseDown does not work. Please use MouseUp.
private void UltraGrid1_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
Point point = new System.Drawing.Point(e.X, e.Y);
UIElement uiElement = ((UltraGridBase)sender).DisplayLayout.UIElement.ElementFromPoint(point);
UltraGridCell cell = (UltraGridCell)uiElement.GetContext(typeof(UltraGridCell));
if (cell.Band.Index == 0)
{
if (cell.Column.Key.Equals("ColumnToShow"))
{
contextMenuStrip.Show();
}
else
{
contextMenuStrip.Hide();
}
}
}
}
}
I have an object that I'm testing that raises an event. What is the best way of using Rhino Mocks to check that it was raised?
Best I could come up with (I am certain it gets better than this):
public void MyCallback(object sender, EventArgs e) { _flag = true;}
[Test]
public void DoSomethingRaisesEvent() {
_flag = false;
using(_mocks.Record()) {
Expect.Call(delegeate { _obj.DoSomething();});
}
using(_mocks.Playback()) {
_obj = new SomethingDoer();
_obj.SomethingWasDoneEvent += new EventHandler(MyHandler);
Assert.IsTrue(_flag);
}
}
I found this article by Phil Haack on how to test events using anonymous delegates
Here is the code, ripped directly from his blog for those too lazy to click through:
[Test]
public void SettingValueRaisesEvent()
{
bool eventRaised = false;
Parameter param = new Parameter("num", "int", "1");
param.ValueChanged +=
delegate(object sender, ValueChangedEventArgs e)
{
Assert.AreEqual("42", e.NewValue);
Assert.AreEqual("1", e.OldValue);
Assert.AreEqual("num", e.ParameterName);
eventRaised = true;
};
param.Value = "42"; //should fire event.
Assert.IsTrue(eventRaised, "Event was not raised");
}
I'm not sure how your test actually calls the DoSomething() Method. Maybe you're missing something to fire the event. Other than that, I think you have are on the right track for testing events with Rhino Mocks
In any case, here is another way I like to deal with events:
[Test]
public void MyEventTest()
{
IEventRaiser eventRaiser;
mockView = _mocks.CreateMock<IView>();
using (_mocks.Record())
{
mockView.DoSomethingEvent += null;
eventRaiser = LastCall.IgnoreArguments();
}
using (_mocks.Playback())
{
new Controller(mockView, mockModel);
eventRaiser.Raise(mockView, EventArgs.Empty);
}
}