.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

GET PROPERTIES ENTITY (MVVM) WHEN SWEEP TO SELECT OBJECT

3 REPLIES 3
SOLVED
Reply
Message 1 of 4
traiduong014969
202 Views, 3 Replies

GET PROPERTIES ENTITY (MVVM) WHEN SWEEP TO SELECT OBJECT

Hi everyone,

Recently, I created a view with a button to retrieve properties of the selected object through a sweep. However, when I click on this button, nothing happens. I'm not sure how to fix it.

Could someone please assist me?

Thank you.

traiduong014969_0-1709736095251.png

// this is code in moddel
public class PropertiesModel : BaseViewModel
{

    public static (string, string) GetSelectedObjectProperties()
    {
        Document doc = Application.DocumentManager.MdiActiveDocument;
        Database db = doc.Database;
        Editor ed = doc.Editor;

        using (Transaction tr = db.TransactionManager.StartTransaction())
        {
            PromptSelectionResult selRes = ed.GetSelection();
            if (selRes.Status == PromptStatus.OK)
            {
                SelectionSet selSet = selRes.Value;
                foreach (SelectedObject selObj in selSet)
                {
                    Entity ent = tr.GetObject(selObj.ObjectId, OpenMode.ForRead) as Entity;
                    if (ent != null)
                    {
                        string color = ent.Color.ColorNameForDisplay;
                        LayerTableRecord layer = tr.GetObject(ent.LayerId, OpenMode.ForRead) as LayerTableRecord;
                        string layerName = layer.Name;
                        return (color, layerName);
                    }
                }
            }
        }

        return (null, null);
    }
}

// this is code in viewmodel
 public class PropertiesViewModel : BaseViewModel
{
    private string _selectedObjectColor;
    public string SelectedObjectColor
    {
        get { return _selectedObjectColor; }
        set
        {
            _selectedObjectColor = value;
            OnPropertyChanged();
        }
    }

    private string _selectedObjectLayer;
    public string SelectedObjectLayer
    {
        get { return _selectedObjectLayer; }
        set
        {
            _selectedObjectLayer = value;
            OnPropertyChanged();
        }
    }

    public ICommand GetPropertiesCommand { get; set; }
   

    public PropertiesViewModel()
    {
        GetPropertiesCommand = new RelayCommand<object>((p) => true, (p) =>
        {
            Entity ent = p as Entity;
            if (ent != null)
            {
                (string color, string layerName) = PropertiesModel.GetSelectedObjectProperties();
                SelectedObjectColor = color;
                SelectedObjectLayer = layerName;
            }

    }
}

// this is code view(xaml)
<UserControl x:Class="MVVM_HCN.MVVM.View.PropertiesView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:MVVM_HCN.MVVM.View"
             mc:Ignorable="d" 
             xmlns:UserControl="clr-namespace:MVVM_HCN.MVVM.View"
             
             d:DesignHeight="100" d:DesignWidth="400" Background="MistyRose"
             xmlns:i="http://schemas.microsoft.com/xaml/behaviors" xmlns:viewmodel="clr-namespace:MVVM_HCN.MVVM.ViewModel" d:DataContext="{d:DesignInstance Type=viewmodel:PropertiesViewModel}">

    <UserControl.DataContext>
        <viewmodel:PropertiesViewModel/>
    </UserControl.DataContext>


    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="200"/>
            <ColumnDefinition Width="auto"/>
            <ColumnDefinition Width="auto"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="25" />
            <RowDefinition Height="auto"/>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="auto"/>



        </Grid.RowDefinitions>
        <TextBlock Grid.Row="0" Grid.Column="0" Text="COLOR">
            
        </TextBlock>
        <TextBlock Grid.Row="1" Grid.Column="0" Text="LAYER">

        </TextBlock>
        <TextBlock Grid.Row="2" Grid.Column="0" Text="GetPerperties">

        </TextBlock>
        <TextBox Grid.Row="0" Grid.Column="1" Width="200"
                 Text="{Binding SelectedObjectColor}">
            
        </TextBox>
        <TextBox Grid.Row="1" Grid.Column="1" Width="200"
                 Text="{Binding SelectedObjectLayer}">

        </TextBox>
        <Button Grid.Row="2" Grid.Column="1"
                Content="GetProperties" Command="{Binding GetPropertiesCommand}" >
            
        </Button>
        <Button Grid.Row="3" Grid.Column="1"
         Content="openfile" Command="{Binding OpenFileName}" >

        </Button>




    </Grid>
</UserControl>
3 REPLIES 3
Message 2 of 4

Any debugging attempts?

 

You can simply place a break point at line 67. If it is not hit, the button is not correctly bound to the GetPropertieCommand property of the viewmodel. If it is indeed hit, you would realize what went wrong: the button did not bind to any command parameter, thus it is null. Also, event you did include "CommandParameter={Binding xxxxx}", I cannot imagine it is an Entity. Therefore, the code in the line 67 would still make no sense, therefore the next line of "if (entity != null)" would still let the code skip to the end (nothing would happen).

 

Norman Yuan

Drive CAD With Code

EESignature

Message 3 of 4
_gile
in reply to: traiduong014969

Hi,

This code seems to have been written by an AI.

 

PropertiesModel

why using a selection to select a single entity? why deriving from BaseViewModel?

It could have been written simply:

 

public class PropertyModel
{
    public static (string, string) GetSelectedObjectProperties()
    {
        Document doc = Application.DocumentManager.MdiActiveDocument;
        Database db = doc.Database;
        Editor ed = doc.Editor;

        var promptEntityResult = ed.GetEntity("\nSelect entity");
        if (promptEntityResult.Status != PromptStatus.OK)
            return (null, null);

        using (Transaction tr = db.TransactionManager.StartOpenCloseTransaction())
        {
            Entity ent = (Entity)tr.GetObject(promptEntityResult.ObjectId, OpenMode.ForRead);
            return (ent.Color.ColorNameForDisplay, ent.Layer);
        }
    }
}

 

 

PropertiesViewModel

The OnPropertyChanged should take the property name as argument.

About the GetPropertiesCommand, @norman.yuan made valuable comments.

I'd write it this way:

 

public class PropertiesViewModel : BaseViewModel
{
    private string _selectedObjectColor;
    private string _selectedObjectLayer;

    public string SelectedObjectColor
    {
        get { return _selectedObjectColor; }
        set
        {
            _selectedObjectColor = value;
            NotifyPropertyChanged(nameof(SelectedObjectColor));
        }
    }

    public string SelectedObjectLayer
    {
        get { return _selectedObjectLayer; }
        set
        {
            _selectedObjectLayer = value;
            NotifyPropertyChanged(nameof(SelectedObjectLayer));
        }
    }

    public ICommand GetPropertiesCommand =>
        new RelayCommand((_) => GetProperties(), (_) => true);

    private void GetProperties()
    {
        (string color, string layer) = PropertyModel.GetSelectedObjectProperties();
        SelectedObjectColor = color;
        SelectedObjectLayer = layer;
    }
}

 

 

BaseViewModel

 

public class BaseViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

 

 

RelayCommand:

 

public class RelayCommand : ICommand
{
    private readonly Action<object> execute;
    private readonly Predicate<object> canExecute;

    public RelayCommand(Action<object> execute, Predicate<object> canExecute = null)
    {
        if (execute == null)
            throw new ArgumentNullException(nameof(execute));

        this.execute = execute;
        this.canExecute = canExecute ?? (_ => true);
    }

    public void Execute(object parameter) => execute(parameter);

    public bool CanExecute(object parameter) => canExecute(parameter);

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }
}

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 4 of 4

@_gile @norman.yuan 

Thank you for your quick response. I just tested your code and followed your debugging suggestions. It worked for me.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Technology Administrators


AutoCAD Beta