열의 버튼, Click 이벤트 핸들러에서 가져온 행 가져 오기


97

내 WPF Datagrid의 itemsource를 내 DAL에서 반환 된 개체 목록으로 설정했습니다. 또한 버튼이 포함 된 추가 열을 추가했습니다. xaml은 아래에 있습니다.

<toolkit:DataGridTemplateColumn  MinWidth="100" Header="View">
    <toolkit:DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <Button Click="Button_Click">View Details</Button>
        </DataTemplate>
    </toolkit:DataGridTemplateColumn.CellTemplate>
</toolkit:DataGridTemplateColumn>

이것은 잘 렌더링됩니다. 그러나 Button_Click 메서드에서 버튼이있는 데이터 그리드의 행을 가져올 수있는 방법이 있습니까? 보다 구체적으로, 내 개체의 속성 중 하나는 "Id"이며 이벤트 처리기의 다른 양식 생성자에 이것을 전달할 수 있기를 원합니다.

private void Button_Click(object sender, RoutedEventArgs e)
    {
        //I need to know which row this button is on so I can retrieve the "id"  
    }

xaml에 추가로 뭔가가 필요할까요, 아니면 로터리 방식으로 진행할까요? 모든 도움 / 조언을 부탁드립니다.

답변:


128

기본적으로 버튼은 행 데이터 개체의 데이터 컨텍스트를 상속합니다. 나는 그것을 MyObject라고 부르고 MyObject.ID가 당신이 원하는 것이기를 바랍니다.

private void Button_Click(object sender, RoutedEventArgs e)
{
    MyObject obj = ((FrameworkElement)sender).DataContext as MyObject;
    //Do whatever you wanted to do with MyObject.ID
}

7
이런 종류의 작업을 수행하는 이상적인 방법은 명령 (기본적으로 MVVM 패턴)을 사용하여 데이터 개체 (ViewModel)에서 명령을 만들고 Button.Command를 호출하여 Button 클릭과 같은 코드 뒤에 코드가 없도록하는 것입니다.
Jobi Joy

1
@JobiJoy : Command / RelayCommand를 사용한 예가 있습니까? 나는 몇 가지 시도하고 있지만 작동하지 않습니다 ..
VoodooChild

내가 본 명령 예제의 문제점은 데이터 그리드에서 선택한 항목을 뷰 모델의 구성원에 데이터 바인딩해야하므로 삭제 버튼에 적합 할만큼 명령을 생성하기가 어렵다는 것입니다. 내 앱에서 거의 모든 것을 삭제하는 데 사용할 수있는 하나의 삭제 버튼 템플릿 열 리소스를 원합니다.
에릭

47

이 작업을 수행하는 또 다른 방법은 ID를 버튼의 CommandParameter 속성에 바인딩하는 것입니다.

<Button Click="Button_Click" CommandParameter="{Binding Path=ID}">View Details</Button>

그런 다음 코드에서 다음과 같이 액세스 할 수 있습니다.

private void Button_Click(object sender, RoutedEventArgs e)
{
    object ID = ((Button)sender).CommandParameter;
}

이벤트와 명령을 혼합하는 이유는 무엇입니까? 명령을 사용하고 명령 매개 변수를 사용하십시오.
ProfK

1
3 개의 답변 : 왜 안됩니까? 간단. 그리고 OP는 명령이 아닌 이벤트 핸들러에 대해 묻습니다. 명령이 과도 할 수 있습니다. 사용 CommandParameter은 속성의 의도 된 용도가 아닐 수 있지만 의미 상 Tag처리기의 바인딩 된 개체에서 ID를 검색하는 것 보다 사용하는 것보다 더 의미 있고 간단합니다. 명령을 선호한다면 그 접근 방식이 좋지만 사용하지 않으려는 경우 복잡성을 추가하는 이유는 무엇입니까?
xr280xr

10

명령 매개 변수 DataContext에 바인딩하고 Jobi Joy와 같은 MVVM을 존중하는 또 다른 방법은 버튼이 데이터 컨텍스트 양식 행을 상속한다고 말합니다.

XAML의 버튼

<RadButton Content="..." Command="{Binding RowActionCommand}" 
                         CommandParameter="{Binding RelativeSource={RelativeSource Mode=Self}, Path=DataContext}"/>

명령 구현

public void Execute(object parameter)
    {
        if (parameter is MyObject)
        {

        }
    }

그렇다면 RowActionCommand가 모델에 있거나 버튼의 데이터 컨텍스트를 ViewModel로 재설정합니까?
Tom Padilla 2014 년

@ PetrŠebesta "RowActionCommand는 각 행보기 모델에 정의되어 있습니다." 이것은 말이되지 않습니다. 그러나 어쨌든 좋은 해결책입니다.
Igor

4
MyObject obj= (MyObject)((Button)e.Source).DataContext;

0

DataGrid의 DataContext가 DataView 개체 (DataTable의 DefaultView 속성) 인 경우 다음을 수행 할 수도 있습니다.

private void Button_Click(object sender, RoutedEventArgs e) {
   DataRowView row = (DataRowView)((Button)e.Source).DataContext;
}

이어야합니다 e.OriginalSource. 대신 e.Source.
Bigeyes

진지하게 Bigeyes, 내 대답은 실제 라이브 코드에서 나온 것입니다!
SurfingSanta
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.