Quantcast
Channel: Windows Presentation Foundation (WPF) forum
Viewing all 18858 articles
Browse latest View live

C# WPF application not responding (with background worker)

$
0
0
I have a WPF application comparing two huge lists of similar entries in a BackgroundWorker object running asynchronously upon a button click. As long as the length of lists is in the 10.000-100.000s range, it runs fine, but once I get into the millions I'm getting the "(not responding)" message in the title bar. The comparison does complete correctly eventually and the applications becomes usable again, but the user might expect the application to have crashed and might attempt to kill the whole thing when the "(not responding)" message is displayed.
Googling this issue, I came across "Application.DoEvents()" that supposed solves this but is part of  WinForms and is not part of WPF. Is there similar functionality in WPF? In other words, what can I do to avoid getting the “not responding” behaviour even for long lists?

I'm updating the console part of the GUI every 10.000 files with a ".", which displays the dots for a while but then stops working once the "not responding" hits.

The comparison takes place in the "runDataCollection" event of the background worker:

using(progressWorker =newBackgroundWorker())
{
    progressWorker.WorkerReportsProgress=true;
    progressWorker.WorkerSupportsCancellation=true;
    progressWorker.ProgressChanged+=newProgressChangedEventHandler(updateListBoxProgress);
    progressWorker.DoWork+=newDoWorkEventHandler(runDataCollection);
    progressWorker.RunWorkerCompleted+=(completeDataCollection);
    progressWorker.RunWorkerAsync();
}
privatevoid runDataCollection(object sender,DoWorkEventArgs e){try{foreach(List<String> cdbStoreBlobIds in cdbStoreBlobIdsLists){foreach(String cdbStoreBlobId in cdbStoreBlobIds){if(fileCount++%10000==0){
                    writeOutput(".",false,false, sender);}for(Int32 i =0; i < xtpNamesList.Count; i++){if(xtpNamesList[i]== cdbStoreBlobId.Split(':')[0]){if(xtpStoreBlobIdsLists[i].Contains(cdbStoreBlobId)){
                            xtpStoreBlobIdsLists[i].Remove(cdbStoreBlobId);break;}}}}}
Cheers,

Simon


Pass custom DependencyProperty from UserControl to ViewModel

$
0
0

Hi,

I have a WPF app with a UserControl with a CustomControl and a ViewModel. I have Registered a few custom Dependency properties and I have issues passing their values to the ViewModel.

I create the DependencyProperty in the UserControl.xaml.cs like this:

  public string SearchPropertyName
        {
            get
            {
                return (string)GetValue(SearchPropertyNameProperty);
            }
            set
            {
                SetValue(SearchPropertyNameProperty, value);
            }
        }

        public static readonly DependencyProperty SearchPropertyNameProperty = DependencyProperty.Register("SearchPropertyName", typeof(string), typeof(SearchBox), new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(OnPropertyChanged)));
        #endregion
 

This method receives the values:

private static void OnPropertyChanged(DependencyObject SearchBox, DependencyPropertyChangedEventArgs eventArgs)

And in the UserControl's CTOR:

 public SearchBox()
        {
            InitializeComponent();
            this.DataContext = new SearchBoxViewModel(SearchPropertyName);
        }   

The problem is, the property gets filled after the DataContext is set.

I have tried working around it in the following ways:

Using MVVMLight Messenger, I send the values when the DependencyProperty is set and register to those events on the VM's CTOR. This worked well(how ever ugly it is) but didn't work for one special property - DataTemplate. I bind a DependencyProperty of type DataTemplate to my ViewModel. That binded property is set using the aformentioned DependencyProperty...which has no value when the XAML is first loaded. I would think it would update like the other properties, but from some reason it does not. I have checked my Binding well and I don't think it's the issue. To be clear, if I set the DataTemplate value in the VM's CTOR, it works. It just won't receive any new value after it.

But the above paragraph is just a stupid workaround which I would love to avoid. I just want to understand how to make the ViewModel create after the DependencyProperties are set. 

I hope I have been clear, thanks for any help!

WPF get Timeline in Code-Behind and manipulate it

$
0
0

I have a set of Storyboard.DoubleAnimations that are declared Resources, the animations work well, however i want to know how to access the Timeline.  I have tried to create a new instance of a Timeline, but could not.  So I must be missing something, and the Timeline does not appear to be accessible from the properties menu.

I have a slot machine that i'm working on; i have animated the ImageBrush property in a Rectangle.Fill object and set it to Tilemode="Tile", this gives me a seamless, slot machine effect.  However, at the moment i have no way to tell when the user wins or loses, or what type of fruit icon shows up.  I have it worked out to 135 pixels between icons, so i get them in the center everytime with some basic math. 

I was hoping to manipulate the Timeline to track the To and From properties in the Storyboard.DoubleAnimation blocks, as the To and From are based on pixel size.  if i can track how many times 135 pixels pass by, i can know exactly what fruit icon is worth what, and then I can determine if the user wins or loses.  Any thoughts on this?

WPF Custom marker

$
0
0

I am using

private static Style ResultStylex()
        {
            Color background = Color.FromRgb(255, 0, 0);
            Style style = new Style(typeof(DataPoint));
            Setter st1 = new Setter(BackgroundProperty, new SolidColorBrush(background));
            Setter st2 = new Setter(HeightProperty, 8.8);
            Setter st3 = new Setter(WidthProperty, 8.8);      
            style.Setters.Add(st1);
            style.Setters.Add(st2);
            style.Setters.Add(st3);
            return style;
        }

to change color and size of datapoints in lineseries.

Is there any easy way to make custom(like triangle or square) datapoint marker in lineseries, just by using DataVisualization toolkit and alike this one style class?

WPF Programmatically set code behind Height or Width to “Auto”

$
0
0

 

Hi,
 
I have a window that has a hidden ListView. When clicking a button on the Window the ListView is populated and made visible if there is any data to show.  I would like the Window to size it's self to 'Auto' programmatically in the code behind if there is Data in the ListView.
 
I've given my Window a name :
 
<Window Name="myWindow" Height="300" Width="350" .....etc > ... </Window>
 
When using intellisense in the code behind it says myWindow.Height is expecting a type of

 

double FrameworkEliment.Height

 

I can set it to a double value

Eg:  myWindow.Height = 500;

 but can’t work out how to set it to “Auto”.

Does anyone know how to set it to Auto?

 

Thanks

 

Matt.

Microchip HID_PnP_Demo, WinForm to WPF.

$
0
0

Hi anyone!

I'm trying to convert a Microchip example code from WinForm to WPF, the example is about an HID that automatically detects, identifies and makes a connection with it (Plug and Play) but I don't know how to solve the "does not contain a definition for 'handle'" error.

//Register for WM_DEVICECHANGE notifications.  This code uses these messages to detect plug and play connection/disconnection events for USB devices
DEV_BROADCAST_DEVICEINTERFACE DeviceBroadcastHeader = new DEV_BROADCAST_DEVICEINTERFACE();
DeviceBroadcastHeader.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
DeviceBroadcastHeader.dbcc_size = (uint)Marshal.SizeOf(DeviceBroadcastHeader);
DeviceBroadcastHeader.dbcc_reserved = 0;	//Reserved says not to use...
DeviceBroadcastHeader.dbcc_classguid = InterfaceClassGuid;

//Need to get the address of the DeviceBroadcastHeader to call RegisterDeviceNotification(), but
//can't use "&DeviceBroadcastHeader".  Instead, using a roundabout means to get the address by
//making a duplicate copy using Marshal.StructureToPtr().
IntPtr pDeviceBroadcastHeader = IntPtr.Zero;  //Make a pointer.
pDeviceBroadcastHeader = Marshal.AllocHGlobal(Marshal.SizeOf(DeviceBroadcastHeader)); //allocate memory for a new DEV_BROADCAST_DEVICEINTERFACE structure, and return the address
Marshal.StructureToPtr(DeviceBroadcastHeader, pDeviceBroadcastHeader, false);  //Copies the DeviceBroadcastHeader structure into the memory already allocated at DeviceBroadcastHeaderWithPointer
RegisterDeviceNotification(this.Handle, pDeviceBroadcastHeader, DEVICE_NOTIFY_WINDOW_HANDLE);

I left the original notes from the Microchip example. The Error happens in the last line.



LINQ instead of for loop in wpf?

$
0
0
i am working wpf richtextbox.i have to get all the lines in richtextbox.So i am using for loop to get all lines.but rtb containslarge textcontent it will take too much of time.so how to get around 1000 line loop in less time.i tried parallel.for but it gives exception because of try to get each line of the RTB text.Here is my code.

   
 for (Int32 icnt = 0; icnt <= iLineCount; icnt++)                    {                        LineDetails lnDtls = new LineDetails();                        lnDtls.LineText = GetLineText(txtAppendValue.CaretPosition.GetLineStartPosition(icnt));                        iCurrentEnd = iCurrentEnd + lnDtls.LineText.Length;                        lnDtls.LineLength = iCurrentEnd;                        listLines.Add(lnDtls);                                            }  


GetLineText():

 

   
 String GetLineText(TextPointer TextPointer)            {                                        tp1 = TextPointer.GetLineStartPosition(0);                    if (tp1 == null)                    {                        return null;                    }                    else                    {                        tpNextLine2 = tp1.GetLineStartPosition(1);                        if (tr != null)                        {                            tr = null;                        }                        if (tpNextLine2 == null)                        {                            tpNextLine2 = txtAppendValue.Document.ContentEnd;                        }                        tr = new TextRange(tp1, tpNextLine2);                        return tr.Text;                    }                               }


So Can i use LINQ instead of  "for loop" for fast execution?

Regards
Sanju

Is there a more up to date way of doing email validation?

$
0
0
I've written validation rules before for various objects, but interestingly enough I've never done it for an email address textbox. So I did a search to find something can I came across this one onWPF Tutorial | Data Validation. It is a good one, but it's also for .NET 3.0. I'm wondering if there's anything more up-to-date for doing validation against email addresses with WPF?

Rod


Android Apps in WPF

$
0
0
Can I use a language like C# and WPF alone and still make a functioning app for Android?

Can wpf run two responsive windows at once?

$
0
0
Window1 calls the other with window2.show, if i touch both windows with my fingers one of the windows is responsive while the other freezes, is this a limitation of wpf or is there a way around this. Tried putting the other window in another thread but the result did not change.

Escape keydown is not fired in WPF window

$
0
0

Hello all,

I am trying to call to show a WPF window from Winform application. Ex: Winform application A will call to show a window B from a WPF DLL. 

I see that the KeyDown event does not fire for Escape key at all on the WPF window when it is focused, but it works with Winform window.

Anyone faced this issue?

Please advise.

Thanks.

AutoCompleteBox binding single property observable collection

$
0
0

Hi 

 I using autocompleteBox. I need binding autocomletebox with single property observable collection.

class Person

                   

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace WpfApplicationAutoComplete
{
    public class Person : INotifyPropertyChanged
    {
        private string _name;
        private string _surname;

        public string Name
        {
            get { return _name; }
            set
            {
                if (_name == value)
                    return;
                _name = value;
                OnPropertyChanged("Name");

            }   
        }

        public string Surname
        {
            get { return _surname;  }
            set
            {
                if (_surname == value)
                    return;
                _surname = value;
                OnPropertyChanged("Surname");
            }
        }

        public Person()
        {

        }

        public Person(string name, string surname)
        {
            _name = name;
            _surname = surname;
        }



        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName = null)
        {
            var handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));

        }

        #endregion



    }
}

MainWindow 

               

public partial class MainWindow : Window
    {
        public ObservableCollection<Person> observ { get; set; }

        public MainWindow()
        {
            InitializeComponent();

            observ = new ObservableCollection<Person>() 
            { 
                new Person { Name = "Adam", Surname = "Smith"}, 
                new Person { Name = "Bill", Surname = "Joel"}, 
                new Person { Name = "Teo", Surname = "Black"}
            };


            this.AutoCompleteBoxOne.ItemsSource = observ;
            this.AutoCompleteBoxOne.ValueMemberPath = Name;

            this.DataContext = this;


        }
    }

how i can do it ? And how i can do it to xaml?

maximun heap size

$
0
0
while I tryed to use a program I got this message?

WPF ToolBar with the ability to set a color of the "overflow panel" and horizontally aligned buttons in "overflow panel"

$
0
0

Hi!

I have faced with the following problems in ToolBar:

  1. Background of the "overflow panel" is always white, even a ToolBar has a specified Background
  2. Button in "overflow panel" are not horizontally aligned

My solution is below... maybe it will be helpfull for someone:

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;

namespace WPF.Controls
{
    public class ToolBar : System.Windows.Controls.ToolBar
    {
        #region Fields

        private Dictionary<Control, Double> _overflowedControlsList = new Dictionary<Control, Double>();
        private ToolBarOverflowPanel _toolBarOverflowPanel;
        private Boolean _suppressOverflowCorrections;
        private Boolean _overflowedControlWidthChanged;

        #endregion //Fields

        #region Properties

        public static readonly DependencyProperty OverflowPanelBackgroundProperty =
            DependencyProperty.Register("OverflowPanelBackground", typeof(Brush), typeof(ToolBar),
            new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender));

        public Brush OverflowPanelBackground
        {
            get { return (Brush) GetValue(OverflowPanelBackgroundProperty); }
            set { SetValue(OverflowPanelBackgroundProperty, value); }
        }

        #endregion //Properties

        #region Public Methods

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            if (OverflowPanelBackground == null)
            {
                OverflowPanelBackground = Background;
            }

            if (_toolBarOverflowPanel == null)
            {
                _toolBarOverflowPanel = GetToolBarOverflowPanel();
                if (_toolBarOverflowPanel == null)
                {
                    return;
                }
                else
                {
                    _toolBarOverflowPanel.Loaded += ToolBarOverflowPanelOnLoadedHandler;
                }
            }

            var overflowPanelBorder = _toolBarOverflowPanel.Parent as Border;
            if (overflowPanelBorder != null)
            {
                overflowPanelBorder.Background = OverflowPanelBackground;
            }
            else
            {
                _toolBarOverflowPanel.Background = OverflowPanelBackground;
                _toolBarOverflowPanel.Margin = new Thickness(0);
            }
        }

        #endregion //Public Methods

        #region Protected Methods

        protected override Size MeasureOverride(Size constraint)
        {
            if (_overflowedControlWidthChanged)
            {
                IsOverflowOpen = _suppressOverflowCorrections = true;
                foreach (var cachedItem in _overflowedControlsList)
                {
                    var control = cachedItem.Key;
                    var width = cachedItem.Value;
                    control.Width = width;
                }
                IsOverflowOpen = _suppressOverflowCorrections = false;
                _overflowedControlWidthChanged = false;
            }

            return base.MeasureOverride(constraint);
        }

        protected ToolBarOverflowPanel GetToolBarOverflowPanel()
        {
            return GetTemplateChild("PART_ToolBarOverflowPanel") as ToolBarOverflowPanel;
        }

        protected ToolBarPanel GetToolBarPanel()
        {
            return GetTemplateChild("PART_ToolBarPanel") as ToolBarPanel;
        }

        #endregion //Protected Methods

        #region Events Handlers

        private void ToolBarOverflowPanelOnLoadedHandler(Object sender, RoutedEventArgs e)
        {
            if (_suppressOverflowCorrections)
            {
                return;
            }

            var width = GetMaxChildWidth(_toolBarOverflowPanel);
            if (width > 0)
            {
                foreach (var child in _toolBarOverflowPanel.Children)
                {
                    var control = child as Control;
                    if (control != null)
                    {
                        if (!_overflowedControlsList.ContainsKey(control))
                        {
                            _overflowedControlsList[control] = control.Width;
                        }
                        if (control.ActualWidth != width)
                        {
                            control.Width = width;
                            _overflowedControlWidthChanged = true;
                        }
                    }
                }
            }
        }

        #endregion //Events Handlers

        #region Private Methods

	private static Double GetMaxChildWidth(Panel panel)
        {
            var width = 0.0;
            foreach (var child in panel.Children)
            {
                var control = child as Control;
                if (control != null && control.ActualWidth > width)
                {
                    width = control.ActualWidth;
                }
            }
            return width;
        }

        #endregion //Private Methods
    }
}

BTW: New ToolBar's "overflow panel" by default has the same background as ToolBar has.

Usage sample:

<Window x:Class="WPF.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:src="clr-namespace:WPF.Controls"><ToolBarTray Background="White">
        <wpf:ToolBar Background="Pink" OverflowPanelBackground="Peru" Band="1" BandIndex="1" Width="50">
            <Button Content="Cut" />
            <Button Content="Copy" />
            <Button Content="Paste" />
        </wpf:ToolBar>
        <wpf:ToolBar Background="Aqua" Band="2" BandIndex="1" Width="70">
            <Button Content="Undo" />
            <Button Content="Redo" />
        </wpf:ToolBar>
        <wpf:ToolBar OverflowPanelBackground="Yellow" Band="2" BandIndex="2" Width="100">
            <Button Content="Paint"/>
            <Separator />
            <Button Content="Spell Check Options" HorizontalContentAlignment="Left" />
            <Separator/>
            <Button Content="Save file" HorizontalContentAlignment="Left" />
            <Separator />
            <Button Content="Open directory" HorizontalContentAlignment="Left" />
        </wpf:ToolBar>
    </ToolBarTray></Window>


New ToolBar Sample


How to get the focus while moving the screen

$
0
0


I acheived to drag and move my application accross the screen when it is in maximized mode with below code.

  private void ControlView_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                if (Window.GetWindow(this) != null)
                {
                    Window.GetWindow(this).DragMove();
                }
            }
        }


private void ControlView_MouseMove(object sender, MouseEventArgs e)
        {

            if (e.LeftButton == MouseButtonState.Pressed
                && Window.GetWindow(this).WindowState == WindowState.Maximized
                )
            {
                Window.GetWindow(this).WindowState = WindowState.Normal;
                if (e.LeftButton == MouseButtonState.Pressed && !(e.LeftButton == MouseButtonState.Released))
                {
                  Window.GetWindow(this).DragMove();

                }
            }
        }

But the issue I face is, When I drag my application while in maximised mode it immediately restores and able to drag it continuosly with left mouse button being pressed as the code highlighted above, but my cursor focus is not present on my title bar( customised title bar is used in my application), as the screen restores my mouse pointer stays in the same place where it was when the screen was in maximised mode.
eg: have to acheive as it works for Ms word. how to do it?


Is it possible to binding the first element of a collection as property in a datagrid?

$
0
0

I have a datagrid in and the item source has a property that is a collection, but I wanted to binding a property of the first element in that collection, so I am trying something like that:

<DataGridCheckBoxColumnHeader="MyColumn"Binding="{Binding MyCollectionProperty.First().MyProperty, Mode=OneWay}"></DataGridCheckBoxColumn>

I guess that I can not use the First() to get the element first element, but it does not work. I have tried with ElementAt(0), but it does not solve my problem.

I know that I could use a converter to do that, but I would like to avoid the converter in this case and do it all in the axml code.

Thanks.

Assembly *.dll must be strong signed in order to be marked as a prerequisite. Even after making strong named

$
0
0

We have a WPF app that we want to use OneClick deployment. After setting up the publish parameters, I get the strong signed message for three of the projects in the solution.  In researching, I found that you could use the Signing tab of the assembly properties page to generate a strong name key file.  Which I did for the three projects that were pointed to in the error.  It generated the pfx files for each in the root of each project.  I then tried to publish again, but got the same message.  Not sure what to do now.  Do I have to do anything to the project that references the three strong name assembly projects?  What is the difference between the generated pfx file and the snk file ext I normally see when looking for info on strong names?

Any help would be appreciated..

Thanks,


Joel WZ


Transfer XAML tab content to PDF doc

$
0
0

Hi Team

Am working in the VSTO application in C# scripting.

I have one requirement to get the contents of the XAML tab transferred to a PDF document. I mean the contents were loaded dynamically to the tab so obviously scroll bars will appear based on the data load. So we should be able to copy one tab content(current tab or all the tabs whichever feasible) to a single PDF document. Don't want to go with third party tools but prefer something already available Windows DLLs or APIs or .NET framework DLLs.

Is there any inbuild Win API to perform this transfer ?? or any clues will help..

Regards

Srinivasan Baskaran


Srinivasan Baskaran, Technology Architect, Infosys Technology Limited, India


Low performance for nested DataGrid while have a lot of columns

$
0
0
Hi all, 
I have a WPF application that contains a datagrid and nested datagrid (RowDetailsTemplate).
For each row have a datagrid that have 1000 rows inside.
I see that nested datagrid have a low performance while i open that.

I also try to set grid height and VirtualizingStackPanel.IsVirtualizing="True", VirtualizingStackPanel.VirtualizationMode="Recycling".
but without successes..


The xaml:

   
<Window x:Class="TestMasterDetails.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"><Grid><DataGrid
            ItemsSource="{Binding Persons}"
            AutoGenerateColumns="False"
              VirtualizingStackPanel.IsVirtualizing="True"
                            VirtualizingStackPanel.VirtualizationMode="Recycling" ><DataGrid.Columns><DataGridTemplateColumn><DataGridTemplateColumn.CellTemplate><DataTemplate><Button Content="+" Click="HandleExpandCollapseForRow"></Button></DataTemplate></DataGridTemplateColumn.CellTemplate></DataGridTemplateColumn><DataGridTextColumn Header="Id" Binding="{Binding Id}"  Width="100"/><DataGridTextColumn Header="FirstName" Binding="{Binding FirstName}"  Width="100"/><DataGridTextColumn Header="LastName" Binding="{Binding LastName}"  Width="100"/></DataGrid.Columns><DataGrid.RowDetailsTemplate><DataTemplate><Grid Height="400"><DataGrid
                            ItemsSource="{Binding Addresses}"
                            AutoGenerateColumns="False"
                            VirtualizingStackPanel.IsVirtualizing="True"
                            VirtualizingStackPanel.VirtualizationMode="Recycling" ><DataGrid.Columns><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/><DataGridTextColumn Header="Id" Binding="{Binding Id}" Width="100"/></DataGrid.Columns></DataGrid></Grid></DataTemplate></DataGrid.RowDetailsTemplate></DataGrid></Grid></Window>



The MainWindow code behind:

    
 public partial class MainWindow : Window
    {
        VM.VM _vm = new VM.VM();
        public MainWindow()
        {
            InitializeComponent();
            DataContext = _vm;
        }

        private void HandleExpandCollapseForRow(object sender, RoutedEventArgs e)
        {
            Button expandCollapseButton = (Button)sender;
            DataGridRow selectedRow = DataGridRow.GetRowContainingElement(expandCollapseButton);

            if (null != expandCollapseButton && "+" == expandCollapseButton.Content.ToString())
            {
                selectedRow.DetailsVisibility = Visibility.Visible;
                expandCollapseButton.Content = "-";
            }
            else
            {
                selectedRow.DetailsVisibility = Visibility.Collapsed;
                expandCollapseButton.Content = "+";
            }
        }
    }



The ViewModel:
      public class VM : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        List<PersonModel> _persons = new List<PersonModel>();

        public List<PersonModel> Persons
        {
            get { return _persons; }
            set
            {
                if (_persons != value)
                {
                    _persons = value;
                    OnPropertyChanged("Persons");
                }
            }
        }
        const int ZERO = 0;
        const int LENGTH = 1000;
        public VM()
        {
            for (int i = ZERO; i < LENGTH; i++)
            {
                var person = new PersonModel() { FirstName = "FirstName" + i.ToString(), Id = i, LastName = "LastName" + i.ToString() };
                for (int j = ZERO; j < LENGTH; j++)
                {
                    person.Addresses.Add(new AddressModel() { Id = j, Address = "Address" + j.ToString() });
                }
                _persons.Add(person);
            }
        }
    }


CollectionViewSource.View not refreshing at end points

$
0
0

I'm running into a problem with my CollectionViewSource.

I'm stopping the user to go BEYOND the the items within the CollectionViewSource to prevent my code from falling over.

I have this:

private CollectionViewSource _source = new CollectionViewSource(); private List<Items> _itemLists; private MyDbContext _context; Constructor() { _itemLists = _context.Items.ToList(); _source.Source = _itemLists; _source.View.CurrentChanged += View_CurrentChanged; } private void View_CurrentChanged(object sender, EventArgs e) { if (_source.View.IsCurrentBeforeFirst) { _source.View.MoveCurrentToFirst(); _source.View.Refresh(); return; } if (_source.View.IsCurrentAfterLast) { _source.View.MoveCurrentToLast(); _source.View.Refresh(); return; } // ... Do some other work here ... }

I had to put in a return statement in each if blocks to prevent the View.CurrentItem from being NULL.

This works great from preventing a Null exception being thrown, but the strange behavior is that when I try to call View.MoveCurrentToNext() after the user tries to go beyond the first record (IsCurrentViewBeforeFirst), nothing happens. You have to call it again in order for the View to be updated to the next record after the first one.

Inversely, the same behavior goes for the IsCurrentViewAfterLast. You have to call View.MoveCurrentToPrevious() twice before the View shows the previous record after the last one when the user tries to go beyond the last record.

So then how can this be fixed so I don't need to call the methods twice?



Viewing all 18858 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>