0

今日、私はやろうとしているうちに夢中になっています。私が思うに、単純なことです。

ユーザーコントロールを作成して、データグリッドの列テンプレートで使用できるようにしたい

いくつかの組み合わせを検索して試しましたが、何も機能していないようです

誰でも私を助けることができますか?

public class User
{
    public string Name { get; set; }
    public bool IsValid { get; set; }
}

partial class MyControl : UserControl
{
    private string _value;
    public string Value
    {
        get { return _value; }
        set { _value = value;
            txt.Text = value;
        }
    }
    public MyControl()
    {
        InitializeComponent();
    }
}

<Grid x:Name="LayoutRoot" Background="White">
    <TextBlock x:Name="txt" Text="[undefined]"></TextBlock>
</Grid>

public partial class MainPage : UserControl
{
    public MainPage()
    {
        InitializeComponent();

        var items = new List<User>();
        items.Add(new User{Name = "user 1", IsValid = true});
        items.Add(new User { Name = "user 2", IsValid = false });

        myGrid.ItemsSource = items;

    }
}

<Grid x:Name="LayoutRoot" Background="White">

    <sdk:DataGrid x:Name="myGrid" AutoGenerateColumns="False" IsReadOnly="True">
        <sdk:DataGrid.Columns>
            <sdk:DataGridTemplateColumn Header="Name">
                <sdk:DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <SilverlightApplication1:MyControl Value="{Binding Name}"></SilverlightApplication1:MyControl>
                        <!--<TextBlock Text="{Binding Name}"></TextBlock>-->
                    </DataTemplate>
                </sdk:DataGridTemplateColumn.CellTemplate>
            </sdk:DataGridTemplateColumn>

        </sdk:DataGrid.Columns>
    </sdk:DataGrid>

</Grid>

編集済み: 次のことも試しましたが、グリッドで結果が得られません:

<Grid x:Name="LayoutRoot" Background="White">
    <TextBlock x:Name="txt" Text="{Binding Value}"></TextBlock>
</Grid>

   public partial class MyControl : UserControl
    {
    public DependencyProperty ValueProperty =
        DependencyProperty.Register("Value",
        typeof(string),
        typeof(MyControl),
         new PropertyMetadata(OnValueChanged));


    public string Value
    {
        get
        {
            return (string)GetValue(ValueProperty);
        }
        set
        {
            SetValue(ValueProperty, value);
            NotifyPropertyChanged("Value");
        }
    }

    private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ((MyControl) d).Value = (String)e.NewValue; //ERROR: here I got always empty string
    }

    public MyControl()
    {
        InitializeComponent();
    }
}
4

2 に答える 2

1

最初のコードが機能しなかった理由は単純です。"MyControl" ( Value={Binding Name}) の "Value" プロパティをバインドできるようにするには、それが依存関係プロパティである必要があります。2番目のコードで修正しました。

これが私がやったことです(そしてそれはうまくいきました):

<UserControl x:Class="BusinessApplication8_SOF_Sandbox.Controls.MyControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             d:DesignHeight="300" d:DesignWidth="400" Name="myControl">
    <Grid x:Name="LayoutRoot" Background="White">
        <TextBlock Name="textBlock" Text="{Binding Value, ElementName=myControl}"/>
    </Grid>
</UserControl>

残りについては、あなたのコードを使用しました。

コントロールを使用する場合のように、データを一方向 (ソースからターゲットへの「一方向」) だけに流したい場合は、「OnValueChanged」でプロパティTextBlockを更新することで問題ありません。TextValue プロパティのコードは次のとおりです。

public static readonly DependencyProperty ValueProperty =
        DependencyProperty.Register("Value", typeof(string), typeof(MyControl),
            new PropertyMetadata("", OnValueChanged));
public string Value
{
   get { return (string)GetValue(ValueProperty); }
   set { SetValue(ValueProperty, value); }
}
private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
   var target = (MyControl)d;
   var oldValue = (string)e.OldValue;
   var newValue = target.Value;
   target.OnValueChanged(oldValue, newValue);
}
protected virtual void OnValueChanged(string oldValue, string newValue)
{
    textBlock.Text = newValue;
} 

xaml でバインドを削除できます。

<TextBlock Name="textBlock" />

これは私にとってもうまくいきました。

お役に立てれば ;)

于 2011-05-02T12:48:23.180 に答える
0

バインドされたプロパティのいずれかが変更された場合に、バインドされたユーザー コントロールが認識できるように、User クラスに INotifyPropertyChanged インターフェイスを実装する必要があります。実装方法の詳細については、次のページを参照してください。http://www.silverlightshow.net/tips/How-to-implement-INotifyPropertyChanged-interface.aspx

ご覧のとおり、インターフェイスを実装する必要があり、セッターでイベント OnPropertyChanged を発生させます

次に、バインディングで動作するはずです。

ベスト、ティム

于 2011-05-02T11:31:19.050 に答える