Silverlight如何在Data Grid列模板中绑定我的usercontrol

时间:2011-05-02 00:36:10

标签: silverlight user-controls datagrid datagridtemplatecolumn

今天我在尝试做的时候变得疯狂,我认为这很简单。

我希望能够创建我的usercontrol,并在我的datagrid中的列模板中使用它

我搜索并尝试了几种组合,似乎没有任何效果

任何人都可以帮助我吗?

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();
    }
}

2 个答案:

答案 0 :(得分:1)

你的第一个代码不起作用的原因很简单。为了能够绑定“MyControl”(Value={Binding Name})上的“Value”属性,它必须是一个依赖属性。你修改了第二段代码。

这就是我所做的(并且效果很好):

<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>

其余的,我使用了你的代码。

另一种可能性,如果您只希望数据在一个方向上流动(从源到目标的“单向”),那么应该没问题,因为使用TextBlock控件的情况就是更新“OnValueChanged”中的Text属性。这是Value属性的代码:

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" />

这也适合我。

希望这会有所帮助;)

答案 1 :(得分:0)

您需要在User类中实现INotifyPropertyChanged接口,以便绑定的用户控件知道是否有任何绑定属性发生更改。请参阅以下页面,详细了解如何实施它:http://www.silverlightshow.net/tips/How-to-implement-INotifyPropertyChanged-interface.aspx

正如您所看到的,您需要实现界面并在setter中引发事件OnPropertyChanged

然后它应该与您的绑定一起使用。

最佳, 添