2017-10-23 2 views
0

사용자에게 자산 목록을 보여주고 목록에서 자산을 삭제할 수있는보기 ('Familify'라고 함)를 작성 중입니다. 자산은 ViewModel의 ObservableCollection에 저장되므로 삭제할 명령은 자산 오브젝트를 가져 와서 콜렉션에서 제거합니다. '삭제'기능을 사용하는 데 문제가 있습니다. 다음은 XAML과 코드 숨김입니다 :사용 방법 x : 데이터 템플릿과 다른 데이터 유형으로 바인딩

Familify.xaml

<ListView 
    ItemsSource="{Binding Assets}"> 
    <ListView.ItemTemplate> 
     <DataTemplate> 
      <Grid> 
       <Grid.ColumnDefinitions> 
        <ColumnDefinition Width="80px" /> 
        <ColumnDefinition Width="*" /> 
        <ColumnDefinition Width="150px" /> 
        <ColumnDefinition Width="*" /> 
        <ColumnDefinition Width="60px" /> 
       </Grid.ColumnDefinitions> 
       <TextBlock 
        Grid.Column="0" 
        Text="{Binding number}" FontFamily="Consolas"/> 
       <TextBlock 
        Grid.Column="1" 
        Text="{Binding type}"/> 
       <TextBlock 
        Grid.Column="2" 
        Text="add binding here"/> 
       <TextBlock 
        Grid.Column="3" 
        Text="add binding here"/> 
       <Button 
        Command="{x:Bind ViewModel.RemoveAssetCommand}" 
        CommandParameter="{Binding}" 
        Content="&#xE894;" 
        FontFamily="Segoe MDL2 Assets" 
        Grid.Column="4"> 
       </Button> 
      </Grid> 
     </DataTemplate> 
    </ListView.ItemTemplate> 
</ListView> 

Familify.xaml.cs

namespace asset_manager.Views 
{ 
    public sealed partial class Familify : UserControl 
    { 
     FamilifyViewModel ViewModel { get; set; } 

     public Familify() 
     { 
      this.InitializeComponent(); 
      DataContextChanged += (s, e) => 
      { 
       ViewModel = DataContext as FamilifyViewModel; 
      }; 
     } 
    } 
} 

는 생각이 버튼을 클릭하면 목록에서 자산을 제거한다는 것입니다 . (그냥 제대로 작동 일반 바인딩 등, number, type을 보여주의한다.) 지금까지 내 생각 : 페이지의보기 모델에 저장된 RemoveAssetCommand에 액세스 할 수 binding를 사용하는

  1. 시도합니다. 그러나 조상 바인딩을 사용할 수 없습니다. 즉, findAncestor은 UWP의 요소가 아니기 때문에 XAML 계층 구조에서 상위 요소의 데이터 컨텍스트를 찾지 못했습니다.
  2. x:Bind 왜냐하면 속성에 대한 명시적인 경로를 사용하기 때문입니다. 따라서, 코드 뒤에서 ViewModel을 선언하면 x:Bind ViewModel.property을 사용할 수 있습니다. 모두 좋고 좋아. 나는 그 일을했으며 IntelliSense를 사용하면 ViewModel.RemoveAssetCommand에 액세스 할 수있었습니다.
  3. 그러나 오류 no DataType defined for DataTemplate이 발생했기 때문에 이것이 작동하지 않았습니다. 이것은 의미가 있으므로 두 가지를 시도했습니다.
  4. (위의 DataTemplate 태그에 삽입)은 데이터 템플릿에 표시된 모델이므로 먼저 시도해 보았습니다. 물론, 명령은 모델에서 선언되지 않으며,보기 모델에서 선언되었으므로 작동하지 않습니다.
  5. 대신 x:DataType="ViewModels:FamilifyViewModel"을 시도했지만 그걸로 x:Bind을 사용할 수 있다고 생각했습니다. 그러나 나는 Asset 타입의 객체를 FamilifyViewModel으로 던질 수 없다는 오류가 발생했습니다. 이 데이터 템플리트로 전달되는 오브젝트가 Asset 유형이기 때문에 이는 의미가 있습니다.

x:Bind이 작동한다고 생각한 전체 이유는 코드 숨김의 ViewModel에서 직접 속성에 액세스 할 수 있기 때문입니다.

명시 적으로 1) ViewModel에서 기본 레벨 속성 (이 경우 Prism 명령)에 액세스하려면 데이터 템플릿에서 x:Bind을 사용할 수 있습니까? 2)이 기능을 구현하는 데 더 좋은 방법이 있습니까?

답변

0

데이터 템플리트에서 x : Bind를 사용하여 ViewModel의 기본 레벨 속성 (이 경우 Prism 명령)에 액세스 할 수 있습니까?당신이 기본 수준에 액세스하려면

예, 당신은 다음과 같이 버튼의 DataContext에 다시 할당 할 수 있습니다 :

Family
<Button DataContext="{Binding ElementName=Familily, Path=DataContext}"/> 

UserControl의 이름입니다.

이 기능을 구현하는 데 더 좋은 방법이 있습니까?

ViewModelcommad을 입력하고 위와 같이 단추를 바인딩합니다. 버튼의 바인드 항목은 Family DataContext이됩니다. 따라서 ViewModel에서 직접 삭제 작업을 호출 할 수 없습니다.

이 기능을 구현하는 가장 좋은 방법은 을 Asset 클래스에 넣는 것입니다. 그리고 ItemsSourceListViewButtonCommandParameter으로 사용하십시오.

<Button 
    Command="{Binding RemoveAssetCommand}" 
    CommandParameter="{Binding ElementName=MyListView, Path=ItemsSource}" 
    Content="&#xE894;" 
    FontFamily="Segoe MDL2 Assets" 
    Grid.Column="4"> 
</Button> 

Asset.cs

public class Asset 
{ 
    public string number { get; set; } 
    public string type { get; set; } 
    public ICommand RemoveAssetCommand 
    { 
     get 
     { 
      return new CommandHandler<ObservableCollection<Asset>>((item) => this.RemoveAction(item)); 
     } 
    } 
    private void RemoveAction(ObservableCollection<Asset> items) 
    { 
     items.Remove(this); 
    } 
} 

ViewModel.cs

public class FamilifyViewModel 
{ 
    public ObservableCollection<Asset> Assets = new ObservableCollection<Asset>(); 
    public FamilifyViewModel() 
    { 
     Assets.Add(new Asset { number = "100001", type = "hello" }); 
     Assets.Add(new Asset { number = "100001", type = "hello" }); 
     Assets.Add(new Asset { number = "100001", type = "hello" }); 
     Assets.Add(new Asset { number = "100001", type = "hello" }); 
    }   
} 

enter image description here

+0

이 완벽, 감사합니다! –

관련 문제